golang中的slice

个00个 · · 622 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

package main

import (
    "fmt"
)

func main() {
    fmt.Println("hello world!")

    x := []int{1,3,4,6,7}
    y := x[2:3]
    fmt.Println(y)
    fmt.Println(len(y))
    fmt.Println(cap(y))

    // 这里不会panic 因为cap(y) = 3. 其输出为 [4 6 7]
    fmt.Println(y[0:3])

    fmt.Println(y[:])
}

上面这段代码神奇的地方就是 注释的部分。 其原因可以参考这篇文章

https://tiancaiamao.gitbooks.io/go-internals/content/zh/02.2.html

关于append时, cap增长的算法 。
参考: https://studygolang.com/articles/18194?fr=sidebar

package main

import (
    "fmt"
)

func main(){
    a := []int{1,2,3}
    b := append(a,4)
    // 1. cap(a) = 3  double = 6  cap(b) = 4 < double ==> cap(b) = double = 6
    fmt.Printf("cap(a)=%v,cap(b)=%v\n",cap(a),cap(b))

    // 2. cap(a) = 3  double = 6  cap(b) = 7 > double ==> cap(b) = 7 ==> roundup +1 => cap(b) = 8
    b2 := append(a, 4, 5, 6, 7)
    fmt.Printf("cap(a)=%v,cap(b2)=%v\n", cap(a), cap(b2))

    // 测试1024
    c := make([]int, 1024, 1024)
    fmt.Printf("cap(c)=%v,len(c)=%v\n", cap(c), len(c))
    d := append(c, 1)
    // 3. len(c) = 1024 , double = 1024 + 1024 / 4 = 1280  cap(d) = 1025 < double => cap(d) = double = 1280
    fmt.Printf("cap(c)=%v,cap(d)=%v\n", cap(c), cap(d))

    c1 := make([]int, 10, 1024)
    fmt.Printf("cap(c1)=%v,len(c1)=%v\n", cap(c1), len(c1))
    d1 := append(c1, 1)
    // 4. 没有触发cap增长。
    fmt.Printf("cap(c1)=%v,cap(d1)=%v\n", cap(c1), cap(d1))
    // fmt.Println(d1)  // [0 1 0 0 0 0 0 0 0 0 1]

    // 5. 制造cap小于doublecap。
    c2 := make([]int, 1023, 1024)
    fmt.Printf("cap(c2)=%v,len(c2)=%v\n", cap(c2), len(c2))
    d2 := append(c2, 1, 2, 4)
    // 5. 这里虽然cap(c2) = 1024 但是len(c2) < 1024 => double = 2 * 1024  cap(d2) = 1025 < 2048 => cap(d2) = 2048
    fmt.Printf("cap(c2)=%v,cap(d2)=%v\n", cap(c2), cap(d2))


    // 5. cap小于doublecap。
    c3 := make([]int, 1023, 1026)
    fmt.Printf("cap(c2)=%v,len(c2)=%v\n", cap(c3), len(c3))
    d3 := append(c3, 1, 2, 4, 5)
    // cap(c3) = 1025 len(c3) = 1023 < 1024 => double = 2 * 1025  cap(d2) = 1025 < 2050 => 归一化到2^x = 2304 ... 神奇
        // roundupsize 这个方法对于1024 < size <  32768 的数据进行了分段的映射。 应该是为了避免 内存的碎片化 ... 
    fmt.Printf("cap(c2)=%v,cap(d2)=%v\n", cap(c3), cap(d3))

}

还是很复杂的呢。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:个00个

查看原文:golang中的slice

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

622 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传