Golang中的slice切片

切片

切片的内部实现

  1. 结构
  • 指向底层数组的指针
  • 长度len()
  • 容量cap()
  1. 切片与数组的区别

    初始化数组:var arrayName [length]type{}
    数组会默认把指定长度的值初始化为零值。

  2. 切片的初始化

    var sliceName []type
    默认指针是nil,长度和容量都是0

    sliceName := make([]type,1,2)
    使用make之后,会把切片初始化为0值,可以通过下标访问

    如果使用make([]type,2),会初始化len为2,cap为2的切片。

    Javaer在这里需要注意,此时如果再使用append去添加元素到切片中,默认会有2个元素是0值。

错误示范:

slice := make([]int,6)
for _,value := range slice1{
	slice = append(slice,value)
}
// 最后的结果可能是{0,0,0,0,0,0,slice1....}

正确解法:

slice := make([]int,0,6)
for _,value := range slice1{
	slice = append(slice,value)
}
// 最后的结果是{slice1....}

注意事项:
Go不允许创建cap小于len的切片
切片定义时默认不会初始化底层数组,必须使用make初始化才可以用
把一个切片赋值给另一个切片,彼此共享数据结构

切片的切割

// 假设slice的容量是k
slice[i:j]	从i到j,长度是j-i,容量是k-i,相当于slice[i:j:k]
slice[i:]	从i到最后一个元素
slice[:j]0到j-1
slice[:]	从头到尾,相当于slice复制

注意事项
将切片切成两个切片时,共享底层数组,修改其中一个,也会影响到另外一个
如果两个切片数据没有交集,则修改就不会影响到另一个

切片的扩容

  1. append函数会增加切片的长度,但是不一定会增加切片的容量,取决于长度有没有超过初始化的容量。

  2. append时,如果超过了容量,会进行扩容。元素在1000以内时,都会成倍增长进行扩容。扩容后,新创建的切片跟原来切片的内存空间就不会共享了,修改切片元素的值,不会影响彼此的数据。

切片作为函数参数

切片是引用类型,作为函数的参数,函数内部的切片参数和外部的切片底层数组是同一个对象,函数内部修改的切片会影响外部的参数切片值(map也是一致的引用类型)。

for循环中的range

range循环创建了每个元素的副本,在for循环中修改value的值,不会影响原来的值。
迭代中,使用append和delete会影响到原来的切片或者map字典。

典型的易错点

for _,value := range slice{
	fmt.Println(&value.A)
}

在这个例子中,for循环中每一次拿到的&valua.A均为第一次循环的那一个,新手很容易犯错。
每一次循环,都是重复利用了那一块内存,对那块内存进行循环赋值而已。
因此,解法是在循环中再用一个变量去接收value,或者调用函数,函数会进行copy,也就完成了解耦。

for _,value := range slice{
	v1 := value
	fmt.Println(&v1.A)
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值