【go】切片(slice)

1.切片的底层实现:

type slice struct {
    array unsafe.Pointer //数组指针
    len   int //切片长度
    cap   int //切片容量
}

声明slice后,此时该slice还未被分配空间,但是可以用append插入数据,append操作会自动给slice扩容

    var slice []int
    //slice[0] = 1 //panic: runtime error: index out of range
    slice = append(slice, 1)
    fmt.Println(slice)// 输出:[1]

2.切片的扩容:

只有执行append函数时,切片才会扩容。
当切片的长度len等于容量cap时,再添加数据就会将当前的数据复制到一个更大的数组中,如果数据长度在1024以下的每次扩容到原数组长度的2倍。超出1024时扩容为原来的1.25倍-1.33倍(1/3-1/4之间)(官网给出的是1/4左右)。增加的少了是怕占用的内存过大。

注意以下操作:

    s := []int{7} //[7]
    s = append(s, 1) //[7 1]
    s = append(s, 2)   //此时切片s的len=3;cap=3 [7 1 2]
    x := append(s, 10) //此时是对 切片[7 1 2]的操作
    y := append(s, 20) //此时也是对 切片[7 1 2]的操作
    // x,y两个切片底层的数组指针 指向的是同一块数组存储空间 所以上述语句执行完后 x,y的输出是一样的。
    // 但是注意当cap容量发生变化时,数组指针(地址)改变
    // 例如 y := append(s, 20,30)时x,y的输出就会不一样 [7 1 2 10] [7 1 2 20 30]
    fmt.Println(s, x, y)
    //输出结果:[7 1 2] [7 1 2 20] [7 1 2 20]

3.切片作为函数参数传参:

  1. 切片作为函数参数是地址传递(引用传递), 形参可以修改实参的值。
  2. 切片的截取操作还是在源切片上操作,所以修改截取后的切片中的值 会影响源切片中对应下标的值。
  3. 切片作为函数参数传参时,如果在传入的函数中使用append函数使切片扩容量(切片容量大小发生改变),此时系统底层会把原数组的值复制给一个新的len更大的数组。所以对应切片指向数组的指针(地址)就会改变。这会导致形参改变,实参并未改变。
  4. 切片作为函数参数传递,为避免底层数组发生改变,可以传递地址
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值