arr5 := [5]int{1,2,3,4,5}
arr6 := baseStruct.Modify1(arr5)
fmt.Println(arr5)//打印结果:[1 2 3 4 5]
fmt.Println(arr6)//打印结果:[300 2 3 4 5]
/*
所用函数
func Modify1(array [5]int) [5]int{
array[0] = 300
return array
}
*/
arr7 := []int{1,2,3,4,5}
arr8 := baseStruct.Modify2(arr7)
fmt.Println(arr7)//打印结果:[300 2 3 4 5]
fmt.Println(arr8)//打印结果:[300 2 3 4 5]
/*
所用函数
func Modify2(array []int) []int {
array[0] = 300
return array
}
*/
有疑问加站长微信联系(非本文作者)

这是一个关于array与slice的问题
这两个看起来长得差不多,刚开始的确挺容易弄混淆的
<br/>
明确指定大小即固定长度的为array <br/> 动态改变大小即不固定长度的为slice <br/> 在函数传递中,array是值传递,slice是地址传递 <br/>
<br/> 明确这个就应该很容易理解啦 <br/> arr5 是 array --- 值传递 --- 不改变<br/> arr7 是 slice --- 地址传递 --- 改变<br/> <br/>
传递一个小技巧
在写代码的三个点后面加上golang,代码可以变得高亮
上面预览的格式有点错乱,重新发布一下总结
传递一个小技巧
在写代码的三个点后面加上golang,代码可以变得高亮
楼上讲的不够准确,容易陷入坑里面。Slice并不是
地址传递
,而是一个引用
类型值传递
,传递过程会将变量进行值拷贝引用
类型,本质并不是一个单独的类型,而是由三个部分组成,如下所示elements
是底层数组
的指针,同时也是Slice称之为引用
类型的根本根据楼上3楼的说法,我写了个例子进行测试
实验总结
实验结论
当函数内部发生slice扩容后,会导致底层数组改变,就不会影响外部作用域的底层数组,经以上代码证明是正确的
但是当函数内部发生slice发生减少的时候,则不会导致底层数组改变,会影响外部作用域的底层数组
感谢楼上指出我的错误
剩余疑问
我不确定我是否找对地方,还是我们两者的go版本不一致
我的go版本为go version go1.13 linux/amd64
希望对楼主有点帮助
只有发生
扩容
才会创建新的底层数组,在Golang里面这个扩容
过程有两个不同的逻辑,主要的区别是有没有赋值回原变量
,详细可以看这篇文章:Go语言设计与实现 - 3.2.4 追加和扩容附骚操作:
Golang没有显性告诉开发者Slice的结构,若是开发者有需求,这可以通过
reflect.SliceHeader
查看或直接修改楼上解答一下疑惑
再次感谢@avtion的解惑
个人平常关注底层理论还是太少、太浅 (厚脸皮不承认自己水平不够)鉴于楼上的解答,知道了golang的slice的魔幻操作
所以我对这个问题进行了一下拓展,思考除slice外的map,struct,[]struct,[]map的修改,会有什么不同?
先上结论:
鉴于我的测试代码实在太多,发布在这里排版可能不太好看,所以需要去github看
github地址: https://github.com/GrayMi/goNote/tree/master/0001-go%E8%AF%AD%E8%A8%80%E5%A4%8D%E6%9D%82%E7%B1%BB%E5%9E%8B%E7%9A%84%E4%BC%A0%E5%80%BC%E4%B8%8E%E4%BC%A0%E5%9D%80
如有发现错误或有歧义的地方,请帮忙指出,谢谢!
@xuanwen @avtion谢谢二位的解答,让我感受到初次来到的这个社区的温暖