考虑以下示例:
type House struct{}
func main() {
house1 := new(House)
house2 := &House{}
fmt.Printf("%T | %T\n", house1, house2)
}
Output: *main.House | *main.House
两个赋值都会产生一个指向类型的指针House
(来自包 main)。
来自 go docunew
:
// The new built-in function allocates memory. The first argument is a type,
// not a value, and the value returned is a pointer to a newly
// allocated zero value of that type.
两个作业中的内存分配在技术上是否相同?有最佳实践吗?
两个作业中的内存分配在技术上是否相同?
我不会谈论实现细节,因为这些细节可能会改变,也可能不会改变。
从语言规范的角度来看,是有区别的。
分配与new(T)
遵循以下规则分配 https://golang.org/ref/spec#Allocation(我自己的注释[斜体]):
内置功能new
需要一个类型T
,在运行时为该类型的变量分配存储空间,并返回该类型的值*T
指着它。该变量按照初始值部分中的描述进行初始化。 [它的零值]
使用复合文字进行分配&T{}
遵循以下规则复合文字 https://golang.org/ref/spec#Composite_literals and 寻址 https://golang.org/ref/spec#Address_operators:
复合文字为结构体、数组、切片和映射构造值,创造新价值每次对他们进行评估时。
获取复合文字的地址会生成指向唯一变量的指针使用文字值初始化.
So both new(T)
and &T{}
分配存储并产生类型的值*T
。然而:
-
new(T)
接受任何类型,包括预先声明的标识符int
and bool
,如果您只需要使用一行代码初始化此类变量,这可能会派上用场:
n := new(int) // n is type *int and points to 0
b := new(bool) // b is type *bool and points to false
-
new
(quoting Effective Go https://golang.org/doc/effective_go#allocation_new) "does not initialize1 that memory, it only zeros it". I.e. the memory location will have the type's zero value.
- 复合文字只能用于结构体、数组、切片和映射
- 复合文字可以通过显式初始化结构体字段或数组/切片/映射项来构造非零值
底线:正如Effective Go 所指出的(与上面的段落相同):
如果复合文字根本不包含任何字段,它会为该类型创建零值。表达式new(T)
and &T{}
是等价的。
[1]:规范和Effective Go 中术语“初始化”的使用不一致。要点是new
您只能产生零值,而复合文字允许您构造非零值。显然,规格才是真相的来源。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)