之前虽然写过一篇值传递和引用传递的文章来讨论这个,但是当时还是太年轻了,写的过于理论化,今天遇到个坑,靠着gpt给我解读,今天总算是把这个知识点巩固好了,直接上结论。
值传递就是把传进来的值copy一份在函数体内使用,引用传递就是把外部变量对象在内存中的地址。
golang写的太少,忘了go的参数传递全都是按值传递的,也就是说,无论传递的是结构体还是结构体的指针,到了函数体内部实际上都是一份copy。
这是一份错误的代码:
var a = "a"
func c (a *string){
b := "b"
a = &b
}
c(&a) //a
注意这里函数体内部的a实际上是&a的副本,也就是说是一个新的字符串,跟外部的a完全没有关系,所以外部的a根本不会发生改变,如果需要修改a的值,正确的写法如下:
var a = "a"
func c (a *string){
b := "b"
*a = b
}
c(&a) //b
也就是说,使用copy出来的a的指针,进行解引用来修改a里的值才是对的。
顺便说下java和c#的按引用传递:java和c#的堆对象是按引用传递的,但严格上来说是”按共享调用”或者”按引用的值传递”,换句话说,你可以修改该对象内部的字段,但不能直接把该对象替换为别的对象,因为这样的话内存地址整个都变了,所以修改不会在外部生效。