zoukankan      html  css  js  c++  java
  • 关于golang slice切片的一个问题

    slice[i:j:k]其中 i 表示从 slice 的第几个元素开始切,j 控制切片的长度(j-i),k 控制切片的容量(k-i),如果没有给定 k,则表示切到底层数组的最尾部。

    注意: k控制切片的容量,不是说k的值是多少就是cap是多少,cap=k-i

    func testCapNotEnough() {
    	slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    	cut := slice[1:3:3]
    	fmt.Println("before slice:", slice)
    	fmt.Println("before cut:", cut)
    	fmt.Println("before cut's cap:", cap(cut))
    
    	cut[0] = 9
    	cut = append(cut, 99)
    
    	fmt.Println("after slice:", slice)
    	fmt.Println("after cut:", cut)
    	fmt.Println("after cut's cap:", cap(cut))
    }
    
    **output:**
    before slice: [1 2 3 4 5 6 7 8 9 10]
    before cut: [2 3]
    before cut's cap: 2
    after slice: [1 9 3 4 5 6 7 8 9 10]
    after cut: [9 3 99]
    after cut's cap: 4
    

    再看下面的代码:

    func testCapEnough() {
    	slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    	cut := slice[1:3:4]
    	fmt.Println("before slice:", slice)
    	fmt.Println("before cut:", cut)
    	fmt.Println("before cut's cap:", cap(cut))
    
    	cut[0] = 9
    	cut = append(cut, 99)
    
    	fmt.Println("after slice:", slice)
    	fmt.Println("after cut:", cut)
    	fmt.Println("after cut's cap:", cap(cut))
    }
    
    **output:**
    before slice: [1 2 3 4 5 6 7 8 9 10]
    before cut: [2 3]
    before cut's cap: 3
    after slice: [1 9 3 99 5 6 7 8 9 10]
    after cut: [9 3 99]
    after cut's cap: 3
    

    为什么只有一个一行代码的差距,结果差距这么大
    cut := slice[1:3:3]
    cut := slice[1:3:4]
    不仅源slice结果都不一样,cut结果也不一样
    cut := slice[1:3:3] 表示cut的容量cap=3-1,而切片从slice上也是切下[1:3]两个元素,也就是如果这时候如果append一个元素99到cut,cut切片的容量是不够的,只能重新开辟一片内存,将数据拷贝过去,然后再将新增的元素99加到末尾,所以这时候的cut和slice已经不是同一个内存了。这就解释了为什么testCapNotEnough()里append之后,slice里没有99这个值,另外append之前cut的cap是2,而元素数量也是2,所以append需要需要扩容将cap翻倍,也就是2翻一倍,所以append之后cut的cap是4。

    再看看testCapEnough(), cut := slice[1:3:4],从slice上也是切下[1:3]两个元素,但是切片的时候,cut的容量cap为4-1=3,也就是说这时候cut的容量还没有满,还能再append一个元素,同时内存空间还是跟slice共用同一个,所以append一个99进去的时候,slice和cut两个切片都会有变化。

  • 相关阅读:
    Android Apk获取包名和Activity名称
    SoupUI接口测试学习分享
    Android 手机自动化测试工具有哪几种?
    SVN和CVS的区别
    名词
    本地解析地址步骤
    python3.6.1+selenium3.0环境安装问题及解决方法
    简述企业信息化与企业架构关系
    企业架构实践的线下公开课学习感悟
    golang 12.9 go mod 实践
  • 原文地址:https://www.cnblogs.com/werben/p/15380330.html
Copyright © 2011-2022 走看看