Golang slice的使用方法及注意事项

马谦马谦马谦 2017年8月26日23:30:25 发表评论
文章最后编辑于:2017-12-5 22:06:40

一、说明

切片(slice)是golang里面的可变长元素类型,不是数组或数组指针,本质是一个结构体

slice的声明如下(位于安装目录下的src/runtime/slice.go):

值得注意的是,切片除了有一个len属性表明当前切片长度以外,还有一个容量标识cap,表示切片的最大容量,len小于等于cap。查看长度和容量的方法很简单,直接使用len()cap()即可。

二、创建方式

1.直接创建

也可以使用索引号指定

2.基于数组创建

通过给定数组的下标范围来创建切片,创建的时候,切片长度等于我们实际赋值的长度,容量默认等于数组第一个被赋值的元素最后一个元素的距离:

这个距离也可以显式指定:

s_data := data[x:y:z]的含义如下:

  • x表示赋值的起始索引,从x开始赋值。
  • y表示赋值的结束索引,长度就是x-y的距离。
  • z表示容量最大可以到的索引,x-z的距离是容量。

通过数组创建的切片和数组共享同一块内存区域,修改切片的时候数组也会随之改变:

3.使用make创建

语法形式是make([]Type, Len, Cap),Type是想要创建的切片类型,Len是切片长度,Cap是切片容量。

cap不是必需的,可以省略不写,默认等于len:

三、使用示例

输出:

四、和数组定义的区别

1.数组的定义:

s := [3]int{1, 2, 3}

s := [...]int{1, 2, 3}

2.切片的定义:

s := []int{1, 2, 3}

s := make([]s, 3)

五、注意事项

切片本质是一个结构体,使用时拷贝传递。在使用切片做函数形参时,会创建一个临时变量,但内部的数据还是不变。

输出:

可以看到s的地址变了,但是内部s[0], s[1]的地址还是一样的,说明在创建副本的时候只是简单拷贝了切片的值,并没有把内部的内存空间重新分配。所以当我们使用range或者把切片作为函数形参时在代码块内部直接就会修改切片的值。

但是在要注意的是在把切片作为函数形参时,在函数内部使用append就不会对切片产生影响:

原理很简单,因为append会返回一个新的slice给a,而as的一个副本,所以这里对s就不会有任何影响,此时要想修改s可以把切片改成指针类型:

 

本文共执行41次查询,耗时0.281秒!
马谦马谦马谦

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: