Append not making sense

agolangf · · 415 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hey everyone,</p> <p>I&#39;m going through <strong>A Tour of Go</strong> and came upon this exercise:</p> <pre><code>package main import &#34;fmt&#34; func main() { var s []int printSlice(s) // append works on nil slices. s = append(s, 0) printSlice(s) // The slice grows as needed. s = append(s, 1) printSlice(s) // We can add more than one element at a time. s = append(s, 2, 3, 4) printSlice(s) } func printSlice(s []int) { fmt.Printf(&#34;len=%d cap=%d %v\n&#34;, len(s), cap(s), s) } </code></pre> <p>The results are:</p> <pre><code>len=0 cap=0 [] len=1 cap=1 [0] len=2 cap=2 [0 1] len=5 cap=6 [0 1 2 3 4] </code></pre> <p>The first 3 function calls I get. But in that fourth function call, why did the capacity go up to 6? Following the pattern, it seems it should be 5. Can anyone explain?</p> <hr/>**评论:**<br/><br/>dlsniper: <pre><p>You can see the explanation here: <a href="https://github.com/golang/go/blob/f3e0d143131dc318a173f4f5cc4e4b96de93318d/src/runtime/slice.go#L72" rel="nofollow">https://github.com/golang/go/blob/f3e0d143131dc318a173f4f5cc4e4b96de93318d/src/runtime/slice.go#L72</a></p> <p>TL;DR: it grows using a predetermined pattern in order to avoid moving the slice elements too much in memory when called in for loops for example.</p></pre>Isaluteyou: <pre><p>Here is the relevant section of the spec: <a href="https://golang.org/ref/spec#Appending_and_copying_slices" rel="nofollow">https://golang.org/ref/spec#Appending_and_copying_slices</a>. The only requirement is that there is enough capacity to hold the values.</p> <blockquote> <p>If the capacity of s is not large enough to fit the additional values, append allocates a new, sufficiently large underlying array that fits both the existing slice elements and the additional values. Otherwise, append re-uses the underlying array.</p> </blockquote></pre>

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

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