首先,我目前是C++开发,在自学Go,当然你教他Golang也可以,其实就是Go。然后目前学习的方法就是照着本文最后吗的链接上的教程敲代码,然后思考和c++/python/java/lua有什么不同。虽然学习的很多,但是我不算特别精通,因为实战只用过c++/lua,所以想在这里记录一下。
今天看到了下面链接里面讲到的函数的可变参数传参,这里不同于c++的可变参数,c++的可变参数是需要通过递归的方式展开的。这里go默认就提供了方法,可以直接解析,也就是,可变参数相当于为参数创建了切片,将切片传入函数。所以函数内如果对于切片进行修改,切片引用的那个数组(那组可变参数)也会发生相应改变。
最后这里解析一下下面这个例子。
1 package main 2 3 import ( 4 "fmt" 5 ) 6 7 func change(s ...string) { 8 s[0] = "Go" 9 s = append(s, "playground") 10 fmt.Println(s) 11 } 12 13 func main() { 14 welcome := []string{"hello", "world"} 15 change(welcome...) 16 fmt.Println(welcome) 17 }
这里的情况分几部分。分条列出如下:
1. 第14行welcome是一个切片(切片和数组的区别为数组定长,而切片边长)
2. 第15行通过...语法糖将welcome这个切片传入change函数,而切片传参时,切片本身做了一次拷贝,即实参和形参的切片并不是同一个切片,只不过他们都引用了同一个数组
3. 第8行,改变了切片第一个元素"hello"->"Go",相应实参welcome对应的数组里面第一个元素也变成了"Go",所以目前切片welcome为{"Go","world}
4. 第9行对传入的切片进行了追加操作,根据之前的知识可以得出,追加之后s现在引用的数组容量是原数组的2倍,即容量为4,将原来的数组拷贝到新数组一份,然后追加,所以切片s对应的数组现在是{"Go","world","playground"},而main函数内的引用welcome目前还是第8行中的{"Go","world"}
5. 所以结果应该是输出了
[Go,world,playground]
[Go,world]
6. 如果读者不知道为什么5中结果是这个,请反复阅读4,并且确认一下切片和数组相关的知识。下面第二个链接里面有详细的切片和数组的知识。
参考链接: