在Go中使用new vs var

时间:2012-09-08 09:11:10

标签: pointers go

你有一个带参数的函数,一个指向类型的指针。

type bar struct{...}

func foo(arg *bar)

之间有什么区别:

var b bar
foo(&b)

b := new(bar)
foo(b)

使用new会创建一个分配。

3 个答案:

答案 0 :(得分:11)

不,没有区别,因为,与C相反,Go明确声明您可以指定本地创建的变量。

来自the documentation

  

请注意,与C不同,返回a的地址是完全可以的   局部变量;与变量关联的存储仍然存在   函数返回后

答案 1 :(得分:4)

两者都应该表示与使用相同默认值初始化的同一对象相同的指针。

spec确实提到了:

  

type T struct { i int; f float64; next *T }
t := new(T)
  

以下成立:

t.i == 0
t.f == 0.0
t.next == nil
  

之后也是如此
var t T

此外:

  

获取复合文字的地址(§Address operators)会生成指向文字值的唯一实例的指针。

var pointer *Point3D = &Point3D{y: 1000}

答案 2 :(得分:-4)

在某些情况下存在差异。 new(T),顾名思义,返回一个类型为T的新实例,而var b T是一个实例,一次又一次(错误,实际上直到它的生命周期结束==走出范围,无法到达......)。

考虑这个循环

var b bar
for i := 0; i < 10; i++ {
    foo(&b)
}

VS

var b *bar
for i := 0; i < 10; i++ {
    b = new(b)
    foo(b)
}

在后一种情况下,如果foo例如将arg存储在某个容器中,则会产生10个bar个实例,而前一个只有一个实例 - 变量{{ 1}}。

另一个不同之处在于性能。变量b或者是一个完全静态的全局变量,或者通常位于某个函数/方法调用记录中的静态已知偏移量(通常是堆栈帧的奇特名称)。 b OTOH,如果没有被编译器优化,则是内存分配器调用。这样的电话会花费一些非零时间。如果在循环中进行而不是实际需要,那么它会使某些代码路径明显减慢。