跳到主要内容

Go make 和 new 的区别

· 阅读需 2 分钟
素明诚
Full stack development

对比 new 和 make

对比项newmake
函数功能分配内存并返回指向零值的指针分配内存并返回初始化的引用类型实例
返回类型指针引用类型实例(非指针)
使用类型所有类型切片、映射、通道
初始化内存初始化为零值内存初始化为特定的非零值(如切片的结构信息)
场景需要类型零值的指针时使用需要立即使用的切片、映射或通道

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 仅适用于切片、映射和通道。
  • 初始化细节:容易混淆切片的容量和长度,可能导致内存浪费或逻辑错误。