Go语言之切片slice

定义

Go语言中切片是对数组的抽象。

由于在Go语言中,数组的长度不可改变,但是在特定场景中这样的集合就不太适用,所以Go中提供了一种灵活、功能强悍的内置类型——切片(可以理解为"动态数组"),与数组相比,切片的长度是可变的,可以往右边追加元素,在追加时可能使切片的容量增大。


切片的两个重要的概念是长度(len)和容量(cap),下面我们通过一段代码来理解下这两者的区别


slice1 := make([]int, 5)
slice2 := make([]int, 5, 8)
arry1 := []int{1,2,3,4,5}
slice3 := arry1[2:4]

如上述,有3种方式定义切片,第一种长度和容量一直,都是5,第二种长度是5,容量为8,而第三种长度为2,容量为3。


大家都知道,实际使用切片比较多的场景,都是基于数组的,即上述的第三种方式。

既然切片是基于数组的,那么切片对其值的改变,是否会影响基础数组的值呢?假设基础数组上有两个切片,他们之间值得改变会互相影响么?切片长度增加(append)会有什么影响?

我们通过代码来回答上述问题

代码1

a1 := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s1 := a1[3:6]
s2 := a1[3:7]
s1[0] = 222

fmt.Println(a1, len(a1), cap(a1), &a1)
fmt.Println(s1, len(s1), cap(s1), &s1)
fmt.Println(s2, len(s2), cap(s2), &s2)

运行结果 

[0 1 2 222 4 5 6 7 8 9] 10 10
[222 4 5] 3 7
[222 4 5 6] 4 7

从结果可以看出,修改了切片1的值,基础数组和切片2对应位置的元素的值都改变了

代码2

a1 := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s1 := a1[3:6]
s2 := a1[3:7]
s1 = append(s1, []int{1111, 1112}...)

fmt.Println(a1, len(a1), cap(a1))
fmt.Println(s1, len(s1), cap(s1))
fmt.Println(s2, len(s2), cap(s2))

运行结果:

[0 1 2 3 4 5 1111 1112 8 9] 10 10
[3 4 5 1111 1112] 5 7
[3 4 5 1111] 4 7

上述结果可以看出,当切片append时,新长度没超出容量,此时对其他切片机基础数组也同样存在影响

代码3

a1 := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s1 := a1[3:6]
s2 := a1[3:7]
s1 = append(s1, []int{1111, 1112, 1113, 1114, 1115, 1116}...)

fmt.Println(a1, len(a1), cap(a1))
fmt.Println(s1, len(s1), cap(s1))
fmt.Println(s2, len(s2), cap(s2))

运行结果:

[0 1 2 3 4 5 6 7 8 9] 10 10
[3 4 5 1111 1112 1113 1114 1115 1116] 9 14
[3 4 5 6] 4 7

可以发现,此时基础数组和切片2都没收到影响,为什么会出现此现象呢?

其实是因为切片1之前的长度是3,容量是7,此时append了6个元素,即长度3+6>7,此时切片的容量不够了,需要进行扩容。而对于切片的扩容,当其容量小于1024时,容量直接翻倍,所以更新后的切片1容量为7*2=14,而切片一旦扩容,切片包括其基础数组都脱离原来的数组,变成基于新的数组的新切片,所以此时原来的基础数组及切片2均不受影响。

 

那么切片扩容之后长度超过了1024时怎样的呢,有兴趣的可以自己动手验证下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值