Go make 和 new 的区别
· 阅读需 2 分钟
对比 new 和 make
对比项 | new | make |
---|---|---|
函数功能 | 分配内存并返回指向零值的指针 | 分配内存并返回初始化的引用类型实例 |
返回类型 | 指针 | 引用类型实例(非指针) |
使用类型 | 所有类型 | 切片、映射、通道 |
初始化 | 内存初始化为零值 | 内存初始化为特定的非零值(如切片的结构信息) |
场景 | 需要类型零值的指针时使用 | 需要立即使用的切片、映射或通道 |
new
函数适用于所有类型,它分配内存并返回一个指向零值的指针。它适用于你只需要一个指向某类型零值的指针的场景。
make
函数专用于切片、映射和通道这些内建的引用类型,它不仅分配内存,还负责初始化这些类型的内部数据结构,使得实例可以立即使用。
理解零值
比如说,如果你执行 ptr := new(int),ptr 是一个指向 int 类型的指针
- ptr 指向的内存区域包含的 int 值被初始化为 0(int 类型的零值)。
- 因此,*ptr == 0 将返回 true,因为 ptr 指向的 int 值是其零值。
如果是 ptrStruct := new(MyStruct),其中 MyStruct 是一个包含多个字段的结构体
- 每个字段都会被初始化为相应类型的零值。如果有整型字段,它们会被设置为 0;如果有字符串字段,它们会被设置为空字符串 "";如果有指针字段,它们会被设置为 nil。
- 所以,ptrStruct 指向的 MyStruct 实例在所有字段上都体现了各自类型的零值。
注意事项
new 的使用
- 零值误解:新手可能会误解
new
创建的是已初始化的对象,尤其是复杂的结构体。 - 引用类型字段:
new
创建的结构体中的切片、映射或通道字段默认为 nil,需要额外的初始化步骤。
make
的使用
- 类型限制:
make
仅适用于切片、映射和通道。 - 初始化细节:容易混淆切片的容量和长度,可能导致内存浪费或逻辑错误。