<p>I'm having trouble understanding how to use <code>copy</code> for replacing elements in a slice.</p>
<p>Playground: <a href="http://play.golang.org/p/MvzP3dQBDq">http://play.golang.org/p/MvzP3dQBDq</a></p>
<p>Specifically, it's <code>copy(s[i+1:], s[i:])</code> which I can't make sense of. To me this says, "copy the slice from i onwards into the slice of i+i onwards". To me that seems like it wouldn't modify the original slice at all.</p>
<p>What's a better way to think about this?</p>
<hr/>**评论:**<br/><br/>RalphCorderoy: <pre><p>It doesn't modify the original slice, but the memory backing the original slice. A slice is just a description, (pointer, len, capacity), of a chunk of that backing memory. You are giving two descriptions to <code>copy</code> that happen to be pointing to the same backing memory. As <a href="https://golang.org/ref/spec#Appending_and_copying_slices" rel="nofollow">https://golang.org/ref/spec#Appending_and_copying_slices</a> says, they are allowed to overlap and it copies the minimum of the two lens. Your <code>copy(s[i+1:], s[i:])</code> is pushing the run of elements from i+1 forward one element, leaving duplicates at s[i] and s[i+1].</p></pre>TheMerovius: <pre><blockquote>
<p>What's a better way to think about this?</p>
</blockquote>
<p>What is the problem with thinking about it exactly this way? Because that's exactly what is happening, it copies all the elements from s[i:] to s[i+1:], which effectively means, it moves them all up one element (to make slot i free to insert the new one). With a couple more elements this is more easily visible: <a href="http://play.golang.org/p/86FVKcZdha" rel="nofollow">http://play.golang.org/p/86FVKcZdha</a></p>
<p>Perhaps your confusion is between slices and arrays? i.e. that a slice doesn't really carry it's own memory, but that it's only a view into an array and that the "elements" of a slice are really the elements of the array it points to. So s[i:] and s[i+1:] really point to the same underlying array (which is the same as s). Thus, copying the elements from s[i+1:] to s[i:] moves the elements of the underlying array up one slot, starting from i.</p>
<p>By the way, I don't know what the intended effect of your code is, but if it was supposed to be an insert, i.e. changing []int{0,1,2,3} to []int{0,1,8,2,3}, it's slightly incorrect, as there is a slot missing. You need to do something like this:
<a href="http://play.golang.org/p/ugnvSktSOM" rel="nofollow">http://play.golang.org/p/ugnvSktSOM</a></p></pre>Perhyte: <pre><p>In your last example, you can also fold the copy into the append by appending the end of the slice to the beginning (with a little overlap). This is shorter and ensures that the append doesn't copy the whole slice (if the capacity was full) only to have the subsequent copy immediately overwrite large parts of it if inserting near the start. See <a href="https://play.golang.org/p/bUJdNpKIeB" rel="nofollow">https://play.golang.org/p/bUJdNpKIeB</a></p></pre>TheMerovius: <pre><p>I thought about that too, but preferred cleaner and more understandable code. As OP is apparently a beginner with go and slices in particular, I didn't want to mix too many concepts in and instead illustrate the basics. :)</p></pre>tgulacsi: <pre><p>copy is just an optimized cycle for copying the elements from the source slice onto the destination slice:</p>
<p>for j := i; j < len(s); j++ {
s[i+1 + j] = s[j]
}</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传