介绍文档用了很多段落来解释new()和make()之间的区别,但实际上,您可以在局部范围内创建对象并返回它们。
为什么要使用这对分配器?
介绍文档用了很多段落来解释new()和make()之间的区别,但实际上,您可以在局部范围内创建对象并返回它们。
为什么要使用这对分配器?
当前回答
你能用它做的事情用其他方法做不到:
创建通道 创建一个预分配空间的映射 创建一个预先分配空间的切片,或者使用len != cap
要证明新的合理性有点难。它简化的主要事情是创建指向非复合类型的指针。 下面两个函数是等价的。一个更简洁一点:
func newInt1() *int { return new(int) }
func newInt2() *int {
var i int
return &i
}
其他回答
Go有多种内存分配和值初始化的方式:
科技{…}, &someLocalVar, new, make
在创建复合字面量时也可以进行分配。
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。然后示例代码看起来像这样:
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)
make(Point) // Illegal
make(int) // Illegal
是的,可以将new和make合并为一个内置函数。然而,一个内置函数可能比两个内置函数更容易让新程序员感到困惑。
考虑到以上几点,new和make保持分离似乎更合适。
make function allocates and initializes an object of type slice, map, or chan only. Like new, the first argument is a type. But, it can also take a second argument, the size. Unlike new, make’s return type is the same as the type of its argument, not a pointer to it. And the allocated value is initialized (not set to zero value like in new). The reason is that slice, map and chan are data structures. They need to be initialized, otherwise they won't be usable. This is the reason new() and make() need to be different.
下面是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
你能用它做的事情用其他方法做不到:
创建通道 创建一个预分配空间的映射 创建一个预先分配空间的切片,或者使用len != cap
要证明新的合理性有点难。它简化的主要事情是创建指向非复合类型的指针。 下面两个函数是等价的。一个更简洁一点:
func newInt1() *int { return new(int) }
func newInt2() *int {
var i int
return &i
}
除了在Effective Go中解释的所有内容外,new(T)和&T{}之间的主要区别是后者显式执行堆分配。但是,应该注意的是,这取决于实现,因此可能会发生变化。
比较make和new没有什么意义,因为两者执行完全不同的功能。但这在链接的文章中有详细的解释。
您需要make()来创建通道和映射(以及切片,但这些也可以从数组创建)。没有其他方法来创建这些,所以不能从词典中删除make()。
至于new(),当可以使用结构语法时,我不知道为什么还需要它。但它确实有一个独特的语义含义,即“创建并返回一个将所有字段初始化为零值的结构体”,这很有用。