为什么我要()或新()?

引言文件用了很多段落来解释new()make()之间的区别,但实际上,你可以在本地范围内创build对象并返回它们。

你为什么要用这个(坦率地说是愚蠢的)一对分配器?

你可以做的事情, make你不能做任何其他的方式:

  • 创build一个频道
  • 用预先分配的空间创build一个地图
  • 用空格预分配或用len!= cap创build一个分片

new理由有点困难。 最容易的是创build指向非复合types的指针。 以下两个函数是等价的。 一个更简洁一点:

 func newInt1() *int { return new(int) } func newInt2() *int { var i int return &i } 

Go有多种内存分配和值初始化方式:

&T{...}&someLocalVarnewmake

创build复合文字时也可能发生分配。


new可以用来分配整数等值, &int是非法的:

 new(Point) &Point{} // OK &Point{2, 3} // Combines allocation and initialization new(int) &int // Illegal // Works, but it is less convenient to write than new(int) var i int &i 

通过查看以下示例,可以看出newmake之间的区别:

 p := new(chan int) // p has type: *chan int c := make(chan int) // c has type: chan int 

假设Go没有new make ,但是它具有NEW的内置function。 那么示例代码将如下所示:

 p := NEW(*chan int) // * is mandatory c := NEW(chan int) 

* 是强制性的 ,所以:

 new(int) --> NEW(*int) new(Point) --> NEW(*Point) new(chan int) --> NEW(*chan int) make([]int, 10) --> NEW([]int, 10) new(Point) // Illegal new(int) // Illegal 

是的,合并newmake成为一个单一的内置function是可能的。 然而,单个内置函数可能会导致新的Go程序员比两个内置函数更加混淆。

考虑到上述所有的问题, newmake保持分离似乎更为合适。

使函数只分配和初始化一个slice,map或chantypes的对象。 像新的一样,第一个参数是一个types。 但是,它也可以采取第二个参数,大小。 与new不同,make的返回types与其参数的types相同,而不是指向它的指针。 分配的值被初始化(没有像新的那样被设置为零值)。 原因是slice,map和chan是数据结构。 他们需要被初始化,否则他们将不可用。 这是new()和make()需要不同的原因。

Effective Go的以下例子非常清楚:

 p *[]int = new([]int) // *p = nil, which makes p useless v []int = make([]int, 100) // creates v structure that has pointer to an array, length field, and capacity field. So, v is immediately usable 

除了Effective Go中解释的所有内容之外, new(T)&T{}之间的主要区别在于后者显式执行堆分配。 但是应该指出,这是依赖于实现的,因此可能会有所变化。

因为两者执行完全不同的function,所以将比较与new做法没什么意义。 但是这在链接的文章中有详细的解释。

你需要make()来创build频道和地图(和切片,但是也可以从数组创build)。 没有其他方法可以使这些,所以你不能从你的词库中删除make()

至于new() ,我不知道为什么你需要它时,你可以使用结构语法。 它确实有一个独特的语义,即“创build并返回一个所有字段都初始化为零值的结构”,这可能是有用的。