一尘不染

通过将指针传递给Go中的函数来获取不同的值

go

假设我想将指针传递给函数并通过这样做来更改该指针指向的结构的值。我通常通过取消引用指针来做到这一点:

type Test struct { Value int}
func main() {
   var i Test = Test {2}
   var p *Test = &i
   f(p)
   println(i.Value)  // 4
}
func f(p *Test) {
   *p = Test{4}
}

我的问题是,为什么这段代码不会改变价值

type Test struct { Value int}
func main() {
   var i Test = Test {2}
   var p *Test = &i
   f(p)
   println(i.Value)  // 2
}
func f(p *Test) {
   // ?
   p = &Test{4}
}

而这个做:

type Test struct { Value int}
func main() {
   var i Test = Test {2}
   var p *Test = &i
   f(p)
   println(i.Value)  // 4
}
func f(p *Test) {
   p.Value = 4
}

阅读 232

收藏
2020-07-02

共1个答案

一尘不染

因为这一行:

p = &Test{4}

只需为p变量分配一个新的指针值即可。在f()函数内部,p只是一个局部变量。通过向分配任何新值p,您只是在更改局部变量的值,而 不是
指向的值。

中的p局部变量f()与中的p局部变量无关main()。如果你改变pf(),它不会改变pmain()(这也不会改变尖结构值)。

在第二个示例中:

p.Value = 4

它是以下各项的简写:

(*p).Value = 4

这改变了 尖锐的 价值,因此你会时遵守变化f()的回报。

注意:

顺便提一句,如果在main()函数中将p(地址为main()指针的局部变量)的地址传递给function
f(),则可以修改存储在main的地址p

func f(p **Test) {
    *p = &Test{4}
}

从中main()调用,就像这样:

var i Test = Test{2}
var p *Test = &i
f(&p)
println(i.Value) // 2 - Note that 'i' won't change!
println(p.Value) // 4 - Only the address in 'p' to the new struct value created in f()

但是显然,传递单个指针*Test并修改指针值(p.Value = 4)更有效,更方便且更简洁。

2020-07-02