考虑以下示例:
type House struct{}
func main() {
house1 := new(House)
house2 := &House{}
fmt.Printf("%T | %T\n", house1, house2)
}
Run Code Online (Sandbox Code Playgroud)
输出:*main.House | *main.House
两个赋值都会生成一个指向类型的指针House(来自包 main)。
来自 go 文档new:
// 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.
Run Code Online (Sandbox Code Playgroud)
两个作业中的内存分配在技术上是否相同?有最佳实践吗?
两个作业中的内存分配在技术上是否相同?
我不会谈论实现细节,因为这些细节可能会改变,也可能不会改变。
从语言规范的角度来看,是有区别的。
分配遵循分配new(T)规则(我自己的注释[斜体]):
内置函数
new采用 typeT,在运行时为该类型的变量分配存储空间,并返回*T指向该类型的值。该变量按照初始值部分中的描述进行初始化。[其零值]
复合文字为结构体、数组、切片和映射构造值,并在每次计算它们时创建一个新值。
获取复合文字的地址会生成一个指向用文字值初始化的唯一变量的指针。
因此new(T)和 都&T{}分配存储并产生类型 的值*T。然而:
new(T)接受任何类型,包括预先声明的标识符 asint和bool,如果您只需要使用一行初始化此类变量,这可能会派上用场:n := new(int) // n is type *int and points to 0
b := new(bool) // b is type *bool and points to false
Run Code Online (Sandbox Code Playgroud)
new(引用Effective Go)“不会初始化1该内存,它只会将其归零”。即内存位置将具有类型的零值。底线:正如Effective Go 所指出的(与上面的段落相同):
如果复合文字根本不包含任何字段,它会为该类型创建零值。表达式
new(T)和&T{}是等效的。
[1]:规范和Effective Go 中术语“初始化”的使用不一致。要点是,new您只能产生零值,而复合文字允许您构造非零值。显然,规格才是真相的来源。