Go之数组/切片
Go之数组/切片
初始化
Go中初始化一个数组如下
1 | // 指定长度 |
在Go中,数组的长度是固定的,创建后不可修改。所以一般情况下用切片比较
方便。切片的长度是可变的,比较好用。
初始化一个切片由几种方法。
1 | // 1 、直接通过元素初始化 |
需要注意的是,切片底层是指向一个数组的。参考以下代码
1 | func main() { |
我们可以看到修改切片的值,数组和切片都同样被改变。但是有一种情况是不同的,就是如果我们对切片进行元素追加,此时切片就指向另一个新的底层匿名数组,此时和原数组就没有关系了
如下:
1 | func main() { |
简单总结就是:切片是指向一个底层数组,如果这个底层数组容量不足时,切片会自动扩容,指向另一个新的底层数组,和原来的数组就没有关系
数组和切片作为参数传递给函数
值传递
1
2
3
4
5func Test(arr [4]int) {
arr[1] = 888
}
x := [...]int{1, 2, 3, 4}
Test(x) // x: [1,2,3,4] 值传递不会影响到x的值传递地址
1
2
3
4
5func Test(arr *[4]int) {
arr[1] = 888
}
x := [...]int{1, 2, 3, 4}
Test(&x) // [1,888,3,4] 传递地址,函数内修改会影响外部
切片有点特殊。切片本质上是一个包含3个属性的结构体。3个属性分别是,切片的长度、切片的容量、一个指针指向底层数组
1 | // y是切片 |
- 值传递
需要注意的是,我们通过传递切片也是值传递的(切片本身被拷贝),函数内的修改切片是修改切片的数组指针属性指向的底层数组的,
所以对应底层数组也会被修改。所以有一种错觉,怎么切片值传递,切片值出来被修改了呢。
1 | func Test(arr []int) { |
但是,如果我们在函数内对切片进行追加,此时,我们再去修改,就是修改了另一个底层数组。这时候原切片和原数组,都不会被修改到了。
1 | func Test(arr []int) { |
所以,切片作为函数参数传递,也是符合Go语言的函数参数值传递的理念。
- 地址传递
切片也是可以地址传递的
1 | func Test(arr *([]int)) { |
有之前的分析,就很好理解了。切片传递的是指针,函数内对切片追加,修改就是修改了原切片的指向底层数组的指针指向,指向我们新生成的指针。所以main函数中,
我们打印切片,发现打印值就是我们修改的值,而原数组也不会被更改了。
- Post title:Go之数组/切片
- Post author:flytam
- Create time:2019-12-07 14:20:57
- Post link:https://blog.flytam.vip/Go之数组!切片.html
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.