Go语言函数参数指针:为何initial修改原对象final却不行?
Go指针参数的修改差异解释
先看你提供的代码:
package main import ( "fmt" ) type Numbers struct { x int y int } func initial(number *Numbers) { number.x = 1 number.y = 1 } func final(number *Numbers) { number = &Numbers{2, 2} } func main() { p := Numbers{0, 0} fmt.Println(p) //Prints {0 0} initial(&p) fmt.Println(p) //Prints {1 1} final(&p) fmt.Println(p) //Expected to print {2, 2} but prints {1, 1} }
核心原因:Go的函数参数是值传递,指针参数也不例外
不管传递的是普通值还是指针,Go都会给函数参数创建一个副本。两者的区别在于:
在
initial函数里:
传递进来的number是原指针&p的副本,但这个副本和原指针指向同一块内存地址(也就是main函数里p的位置)。所以通过number.x、number.y修改的,是这块内存里的内容,自然main里的p会跟着变化。在
final函数里:
同样先拿到原指针的副本,但这里做的操作是number = &Numbers{2, 2}——把这个指针副本重新指向了一个新创建的结构体的内存地址。这时候修改的只是副本本身的指向,原指针(main里的&p)依然指向原来的p,所以main里的p内容不会有任何变化。
简单类比:
你有一把钥匙能打开A房间,复制了一把给朋友。朋友用复制的钥匙打开A房间,把里面的东西换了(对应initial),你再开A房间肯定能看到变化;但如果朋友把复制的钥匙换成了B房间的钥匙(对应final),你的钥匙还是开A房间,A房间里的东西当然没变。
内容的提问来源于stack exchange,提问作者ЯДPTГФИ
相关产品推荐
相关产品推荐

