go-questions
go-questions copied to clipboard
切片作为函数参数这一章节,倒数第三段描述应该不准确
问题描述
请在此描述你的问题,提问前请参考提问的智慧
原文是这么说的:
myAppend 函数里,虽然改变了 s,但它只是一个值传递,并不会影响外层的 s,因此第一行打印出来的结果仍然是 [1 1 1]。
这个地方我在第一次看到的时候有点歧义,虽说slice是一个值传递,但是slice中是包含是指向数组的指针的。按理说,值传递的也是数组的指针。
经过验证,不影响的准确原因应该是append触发了slice的扩容,扩容会导致copy,也就是说slice结构体中指向数组的指针发生了变化。因此外层的s不会发生变化。 如果是直接修改slice元素,内外层都会改变
func myAppend(s []int) []int {
//s = append(s, 100)
s[0] = 100
fmt.Printf("s point out func: %p, %p\n", s, &s)
return s
}
我个人的理解,如有不对,欢迎讨论~
这里的描述也感觉有点歧义。
果真改变了原始 slice 的底层数据。这里传递的是一个 slice 的副本,在 f 函数中,s 只是 main 函数中 s 的一个拷贝。在f 函数内部,对 s 的作用并不会改变外层 main 函数的 s。 但就结果来看,对 f函数内s 的作用改变了外层 main 函数的 s。 我理解其实传的不是slice的副本,而是slice指针的副本,因为slice本身就是引用类型变量,所以在f函数中修改s的值,slice的值也被修改。
func main() {
slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Printf("%p\n", slice)
f(slice)
}
func f(s []int) {
fmt.Printf("%p\n", s)
}
输出的结果:
0x1400001c0f0
0x1400001c0f0