Go 中通过 new(Type) 和 &Type{} 分配内存的区别

考虑以下示例:


type House struct{}


func main() {

    house1 := new(House)

    house2 := &House{}

    fmt.Printf("%T | %T\n", house1, house2)

}

输出:*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.

两种分配的内存分配在技术上是否相同?有最佳实践吗?


隔江千里
浏览 94回答 1
1回答

守着星空守着你

两种分配的内存分配在技术上是否相同?我不打算谈论实现细节,因为这些可能会也可能不会改变。从语言规范的角度来看,是有区别的。分配new(T)遵循分配规则(我自己在[斜体]中的注释):内置函数new采用 type T,在运行时为该类型的变量分配存储空间,并返回*T指向该类型的值。变量按照初始值部分中的说明进行初始化。[它的零值]使用复合文字进行分配,&T{}遵循复合文字和寻址的规则:复合文字为结构、数组、切片和映射构造值,并在每次评估它们时创建一个新值。获取复合文字的地址会生成一个指针,该指针指向使用该文字的 value 初始化的唯一变量。所以new(T)和都&T{}分配类型的存储和产量值*T。然而:new(T)接受任何类型,包括预先声明的标识符int和bool,如果您只需要使用单线初始化此类变量,这可能会派上用场:n := new(int) // n is type *int and points to 0 b := new(bool) // b is type *bool and points to falsenew(引用 Effective Go)“不会初始化1那个内存,它只会将它归零”。即内存位置将具有类型的零值。复合文字只能用于结构、数组、切片和映射复合文字可以通过显式初始化结构字段或数组/切片/映射项来构造非零值底线:正如 Effective Go 所指出的(与上述相同的段落):如果复合文字根本不包含任何字段,它会为该类型创建一个零值。表达式new(T)和&T{}是等价的。[1]:规范和 Effective Go 中“初始化”一词的使用不一致。要点是new你只能产生一个零值,而复合文字允许你构造非零值。显然,规格是事实的来源。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go