12

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

type bar struct{...}

func foo(arg *bar)

有什么区别:

var b bar
foo(&b)

b := new(bar)
foo(b)

使用 new 创建分配。

4

3 回答 3

13

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

文档中

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

于 2012-09-08T09:16:08.920 回答
5

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

规范确实提到:

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

还:

获取复合文字的地址(§地址运算符)会生成一个指向该文字值的唯一实例的指针。

var pointer *Point3D = &Point3D{y: 1000}
于 2012-09-08T09:15:39.163 回答
-4

在某些情况下存在差异。new(T),顾名思义,返回一个类型为 T 的新实例,whilevar b T是一个单一实例,一次且永远(错误,实际上直到其生命周期结束 == 超出范围,无法访问......)。

考虑这个循环

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

对比

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

在后一种情况下,foo例如,如果将其存储arg在某个容器中,则会导致 10 个bar存在实例,而前一种情况只有一个变量b

另一个区别在于性能。该变量b将是一个完全静态的全局变量,或者通常位于某些函数/方法调用记录中的静态已知偏移量(通常是堆栈帧的花哨名称)。newOTOH,如果没有被编译器优化,是一个内存分配器调用。这样的调用将花费一些非零时间。如果在循环中进行并且实际上没有必要,那么它可能会使某些代码路径明显变慢。

于 2012-09-08T10:01:20.653 回答