new和make有什么区别?

时间:2014-08-18 07:22:19

标签: go

New不会初始化内存,只会将其归零。它返回一个指向新分配的零值的指针。

Make仅创建切片,地图和通道,并将它们初始化。

"初始化"意味着在这种背景下? new和make之间还有什么区别?

3 个答案:

答案 0 :(得分:18)

Making slices, maps and channels中所述:

  

内置函数make采用T类型,必须是切片,地图或渠道类型,可选地后跟特定类型的表达式列表。
  返回T 类型的值(不是*T)   内存按照initial values一节中的描述进行初始化。

例如,对于Slice type

make([]T, length, capacity)
  

产生与分配数组和切片相同的切片,因此这两个表达式是等价的:

make([]int, 50, 100)
new([100]int)[0:50]

所以在这里,make创建切片,并根据零值初始化其内容(如果使用的类型为int,那么' 0')

您可以在Go: why would I make() or new()?

中查看有关保持新内容和分开内容的更多信息

Dave cheney刚写了一篇好文章:" Go has both make and new functions, what gives ?"

  

虽然make创建了通用slicemapchannel值,但它们仍然只是常规值; make不返回指针值

     

如果new被移除,而make,您将如何构建指向初始化值的指针?

     

使用newslice构建指针mapchannel 零值今天,与new的行为一致。

     

对于他们可能造成的混淆,makenew是一致的;

     
      
  • make仅制作切片,地图和频道,
  •   
  • new仅返回指向初始化内存的指针。
  •   

答案 1 :(得分:2)

第一个区别是类型:make(T, ...)始终返回类型T,而new(T, ...)始终返回类型*T。这告诉你他们非常不同。

new适用于所有类型,并为该类型的变量动态分配空间,初始化为该类型的零值,并返回指向它的指针。

想到它的一种方法是

result = new(T)

总是等同于

var temp T
result = &temp

(换句话说,您可以通过定义给定类型的变量,而不是初始化它,然后获取指向它的指针来执行与new相同的操作。)

make是一种"构造函数"对于某些内置类型(切片,地图或通道)。

答案 2 :(得分:2)

enter image description here 内置的new(T)函数为类型T的新项目分配“清零”存储,并返回其地址,即* T类型的值。在Go术语中,它返回一个指向新分配的类型T的零值的指针。例如,以下三种创建指针p的方法,该指针指向一个零字节。缓冲值,每种等效:

// Allocate enough memory to store a bytes.Buffer value
// and return a pointer to the value's address.
var buf bytes.Buffer
p := &buf

// Use a composite literal to perform allocation and
// return a pointer to the value's address.
p := &bytes.Buffer{}

// Use the new function to perform allocation, which will
// return a pointer to the value's address.
p := new(bytes.Buffer)

另一方面,make()函数是一个特殊的内置函数,用于初始化切片,地图和通道。请注意,make()仅可用于初始化切片,地图和通道,并且与new()函数不同,make()不会返回指针。

切片,映射和通道也可以使用复合文字表达式以及make()进行初始化。下面给出了两种不同的(至今等效的)初始化映射m的方法,该映射m将字符串键映射到bool值:

// Using make() to initialize a map.
m := make(map[string]bool, 0)

// Using a composite literal to initialize a map.
m := map[string]bool{}

// You can also initialize maps with initial data using a composite literal,
// as shown below:
m := map[string]bool{
    "java": false,
    "go":   true,
}