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

时间:2015-12-30 00:26:36

标签: pointers struct 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
}

1 个答案:

答案 0 :(得分:12)

因为这一行:

p = &Test{4}

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

p中的f()局部变量与p中的main()局部变量无关。如果您更改p中的f(),则不会更改p中的main()(并且它也不会更改指向的结构值)。

在你的第二个例子中:

p.Value = 4

这是一个简写:

(*p).Value = 4

这会更改指向的值,因此您会在f()返回时观察到更改。

注意:

作为旁注,如果在main()函数中,您将p的地址(main()中的局部变量是指针)传递给函数{{1} },您可以修改主f()

中存储的地址
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)更有效,更方便,更清晰。