携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第17天,点击查看活动详情
前言
对很多人来说,Go参数传递是值传递还是引用传递,很迷惑。我也一样,经常混淆,今天我来总结一下,方面以后在面试中用,希望对你有所帮助。
什么是值传递
值传递,其字面意思是传递的就是值,传值的意思是:函数传递的总是原来这个东西的一个副本,一副拷贝。比如我们传递一个int类型的参数,传递的其实是这个参数的一个副本;传递一个指针类型的参数,其实传递的是这个该指针的一份拷贝,而不是这个指针指向的值。
示例1:
func main(){
a := 10
fmt.Printf("a原始指针的内存地址是:%p:\n",&a) //a原始指针的内存地址是:0xc00000a0a0
modify(a)
fmt.Println("a值被修改了,新值为:", a) //a值被修改了,新值为: 10
}
func modify(i int) {
fmt.Printf("函数里接收到的指针的内存地址是:%p:\n", &i) //函数里接收到的指针的内存地址是:0xc00000a0a8
i = 100
}
这里验证了go是值传递,但是还不能完全确定go就只有值传递,下面看下示例2:
示例2:
func main(){
a := 10
ap := &a
fmt.Printf("a原始指针的内存地址是:%p\n",&ap) //a原始指针的内存地址是:0xc000006028
modify(ap)
fmt.Println("a值被修改了,新值为:", a) //int值被修改了,新值为: 100
}
func modify(i *int) {
fmt.Printf("函数里接收到的指针的内存地址是:%p\n", &i) //函数里接收到的指针的内存地址是:0xc000006038
*i = 100
}
所以通过输出我们可以看到,这是一个指针的拷贝,因为存放这两个指针的内存地址是不同的,虽然指针的值相同,但是是两个不同的指针。
什么是引用传递
引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
Go语言没有引用传递,这里我不能使用Go举例子。
总结
在Go语言中只存在值传递,要么是值的副本,要么是指针的副本。无论是值类型的变量还是引用类型的变量亦或是指针类型的变量作为参数传递都会发生值拷贝,开辟新的内存空间。另外值传递、引用传递和值类型、引用类型是两个不同的概念,不要混淆了。引用类型作为变量传递可以影响到函数外部是因为发生值拷贝后新旧变量指向了相同的内存地址。