为什么我要()或新()?
引言文件用了很多段落来解释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{...}
, &someLocalVar
, new
, make
创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
通过查看以下示例,可以看出new
和make
之间的区别:
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
是的,合并new
, make
成为一个单一的内置function是可能的。 然而,单个内置函数可能会导致新的Go程序员比两个内置函数更加混淆。
考虑到上述所有的问题, new
和make
保持分离似乎更为合适。
使函数只分配和初始化一个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并返回一个所有字段都初始化为零值的结构”,这可能是有用的。