分享
  1. 首页
  2. 文章

golang中的slice

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

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

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

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏