假设我想传递一个指向函数的指针,并通过这样做来更改该指针指向的结构的值。我通常会通过取消引用指针来执行此操作:
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
}
答案 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
)更有效,更方便,更清晰。