new 和 make 的区别

  • make 和 new 都是用来申请内存地址的
  • new 通常用于给基本数据类型申请内存,返回的是对应类型的指针,如 *string*int
  • make 专用于给 map、slice、channe 申请内存空间,返回的是对应的类型本身

 

在Go语言中,make() 函数主要用于初始化内置的引用类型,如 slices(切片)、maps(映射)和 channels(通道)。它返回的是对应类型的引用(或者说是指向底层数据结构的指针),但是需要注意的是,make() 函数本身并不直接返回指针(*Type)类型,而是返回了这些内置引用类型的实例。然而,由于这些引用类型在Go中是通过指针(或类似机制)来间接访问其底层数据结构的,因此可以认为它们的行为类似于指向这些数据的指针。

这里有一个重要的区别需要理解:当你使用make()函数时,你并没有直接操作指针;你操作的是切片、映射或通道本身,但这些类型在内部是通过指针(或类似机制)来管理其底层数据的。

举个例子,考虑切片(slice):

s := make([]int, 0, 10) // 创建一个长度为0,容量为10的int切片

在这个例子中,s 是一个切片类型的变量,而不是一个指针。但是,切片在内部包含了一个指向其底层数组的指针,以及表示切片长度和容量的整数。因此,当你将切片传递给函数时,你实际上是在传递这个内部指针的副本(但请注意,这个副本仍然指向相同的底层数组)。

尽管make()不直接返回指针,但如果你确实需要一个指向切片的指针,你可以简单地通过取地址操作符&来实现

s := make([]int, 0, 10)
p := &s // p 是一个指向切片的指针

然而,需要注意的是,在这个特定的例子中,p 指向的是一个局部变量的地址(即s),这可能会引入一些不期望的行为,特别是当这个局部变量(在这个例子中是s)在函数返回后被回收时。因此,在实际编程中,除非有特别的理由,否则通常不会这样做。

总的来说,make()函数在Go中用于初始化切片、映射和通道,并返回这些类型的实例,这些实例在内部通过指针(或类似机制)来管理其底层数据。如果你需要直接操作这些类型的指针,你应该谨慎行事,并了解相关的内存管理细节。