切片是什么?
切片是go语言中一种对数组的映射,它可以动态地增长和缩小,而不像数组那样长度固定。切片有三个字段:指向底层数组的指针、切片的长度和切片的容量。
其中,切片的指针,切片的长度,元素数量都会存在数组的开始位置。在日常使用时,如果只看切片,那他更像我们在其他语言中常见的“动态数组”。不过在某些程度上又稍微有所不同。
切片的生成
切片可以通过两种形式生成,一种是用make函数,指定类型、长度和可选的容量;另一种是用字面量,直接给出元素值或者索引值。
var slice []type = make([]type, len)//通过make方法生成切片,可以指定最初大小
也可以通过简写成
slice := make([]type, len)
另一种方法可以是直接声明切片,然后往里面添加数据
var slice[]type
切片可以通过切片表达式来截取切片,例如slice[i:j]表示从索引i到j-1的元素,或者slice[i:j:k]表示从索引i到j-1的元素,并且指定新切片的容量为k-i。值得一提的是,截取出来的切片依然是对底层数组的映射,因此截取后的切片虽然变短了,但是截掉的数据在底层数组依然存在。
要想往切片内添加数据,可以使用append()函数来向切片追加新元素,如果底层数组的容量不够,就会创建一个新的数组,并把原来的元素复制过去。
append(slice,...)
利用copy函数也可以用来对切片和切片之间的数据进行拷贝
copy(a,b)//将数组b数据拷贝到数组a
值得一提的是,不论切片怎么更改数据,实际上更改的是切片指向的底层数组,所以要是两个切片都指向同一个数组,而且进行拷贝,很可能会出问题。
因为底层数组是固定长度,不可更改、扩容的,因此切片的扩容实际上是数组的更换,那势必会进行新的更大容量的数组和原有数组之间的数据拷贝,因此切片一般建议按需求提前划分好大致大小,避免切片频繁扩容导致的数据拷贝对程序和系统带来额外的开销。