1、案例一:
运行结果为:
F:\goweb\mytest> go run main.go
切片的内存地址0xc000010280
切片的内存地址&0xc000010280
切片作为形参传递后的内存地址0xc000010280
切片作为形参传递后的内存地址0xc000008090
从上面案例,我们发现几个问题:
第一:fmt.Printf("切片的内存地址%p", num)与fmt.Printf("切片的内存地址&%p", &num[0]) 结果相同,说明一个问题。num默认地址是切片(数组的一部分)第一个单元。重温“切片”的定义:切片 (slice) 是对数组一个连续片段的引用(该数组我们称之为相关数组,通常是匿名的),所以切片是一个引用类型。从这里可以得到一个结论:num切片是一个地址值,是指向引用数组的第一单元的地址(数组下标为0的索引)。这样就可以理解num地址与&num[0]地址相同了.
第二问题:下面这两个输出会一样吗?
fmt.Printf("切片的内存地址%p", num)
fmt.Printf("切片的内存地址%p", &num)
运行结果如下:两个结果不同,num本身 就是一个指针,也就是一个内存地址,再对num取&,就是获取指针变量的地址。不知道我说清楚了没有?
第三问题:形参arg与实参num的指向都是同一个地址。从这里我们可以判断出来,形参与实参共同引用一个数组内存。那么现在问题来了,假如我们改变形参的值,实参会改变吗?
测试结果如下:形参改变值了,形参地址也改变了。实参并未受到影响。
第四个问题:假如我们不对形参进行追加新单元值,只修改形参的单元值,实参是否改变?
测试:
输出结果:形参与实参的引用地址都没有改变。结果就是形参修改的新值会影响到实参的结果。
结论:切片在形参传递过程中。形参与实参共同引用一个底层数组,只要底层数组长度未改变,形参与实参就是达到引用传递,假如形参切片在被追加单元值导致底层数组必须重建,那么形参的修改就不会影响到实参。这个时候就是值的传递