正本清源--go无引用类型更无引用传递
go语言仅有值传递,go语言在函数调用是仅仅只有一种传递方式就值拷贝。
我们本次主要和大家一起研究指针类型的参数传递。涉及两个方面问题
1、为什么指针也是值传递
2、传递指针是否改变实参
package main
import "fmt"
func main() {
a, b := 1, 2
p1, p2 := &a, &b
fmt.Printf("p1址地:= 0x%p, p2 地址=0x%p p1 = %p, p2 = %p\n", &p1, &p2, p1, p2)
swap(p1, p2)
fmt.Printf("after swap p1址地:= 0x%p, p2 地址=0x%p p1 = %p, p2 = %p\n", &p1, &p2, p1, p2)
fmt.Printf("after swap a = %d, b = %d\n", a, b)
}
func swap(p3, p4 *int) {
*p3, *p4 = *p3, *p4
fmt.Printf("p3地址=%p p4地址 = %p p3 %p, p4= %p\n", &p3, &p4, p3, p4)
}
程序输出结果:
p1址地:= 0x0xc00000e028, p2 地址=0x0xc00000e030 p1 = 0xc00001a0e0, p2 = 0xc00001a0e8
p3地址=0xc00000e040 p4地址 = 0xc00000e048 p3 0xc00001a0e0, p4= 0xc00001a0e8
after swap p1址地:= 0x0xc00000e028, p2 地址=0x0xc00000e030 p1 = 0xc00001a0e0, p2 = 0xc00001a0e8
after swap a = 1, b = 2
从程序运行结果,我们可以分析出:
实参p1、p2是指针,形参p3、p4也是指针
p3、p4和p1、p2 地址不同,值是相同的,都是指向a、b。证明在参数传递过程中,仅仅将p1、p2 拷贝一份传递到函数中。
在调用swap函数前后p1,p2 的地址和值都没有改变。证明传指针不能改变实参。p3 、p4 和p1、p2 是不同的变量,所以改变p3、p4 对p1 、p2 没有影响。
在调用swap 前后a、b 值的改变和参数传递无关,是指针自己的能力,指针能过改变指向变量的值。go有指针变量,就没有引用变量和引用传递的说法,
综上所述:
1、go语言传递指针变量也是值传递
2、go语言传递指针变量也不能改变实参。
3、传递指针变量,可以改变指针指向的变量的值,这是指针的能力和参数传递无关。深入理解参见系列(一)