英文:
Understanding slice assignment in Go
问题
在上述代码片段中,if
块后面的那一行代码 slice = slice[0:l+len(data)]
的作用是什么?
这行代码的作用是将切片 slice
的长度调整为 l+len(data)
。它通过对切片进行切片操作,将切片的长度截取为 l+len(data)
,以便在后续的循环中将 data
中的元素追加到切片末尾。
英文:
In the below code snippet, what exactly is the line after the if
block doing
slice = slice[0:l+len(data)]
?
<!-- language: lang-golang ln:true -->
<!-- ln: true -->
func Append(slice, data []byte) []byte {
l := len(slice)
if l + len(data) > cap(slice) { // reallocate
// Allocate double what's needed, for future growth.
newSlice := make([]byte, (l+len(data))*2)
// The copy function is predeclared and works for any slice type.
copy(newSlice, slice)
slice = newSlice
}
slice = slice[0:l+len(data)] // <-- What is this doing ?
for i, c := range data {
slice[l+i] = c
}
return slice
}
答案1
得分: 2
我猜测
slice = slice[0:l+len(data)]
改变了slice
的长度,因此你可以添加新的元素。
> 你可以通过重新切片来扩展切片的长度,前提是它有足够的容量。
英文:
I guess
slice = slice[0:l+len(data)]
changes slice
length, so you can add new elements.
> You can extend a slice's length by re-slicing it, provided it has sufficient capacity.
答案2
得分: 0
只需扩展slice
的长度,就可以追加数据,删除这个语句,否则会导致slice
索引超出范围。此外,copy
函数返回src
和dst
的最小长度,所以当执行if l + len(data) > cap(slice)
时,slice
的长度将为0。
英文:
just expand the len(slice) ,so can append data, remove this this statement, slice out of index occurs...In addition,copy return the min len(src) and len(dst), so when execute if l + len(data) > cap(slice)
,the len(slice) would be 0
答案3
得分: 0
只是为了以后参考而发布这个答案。
那行代码没有用。在它上面的语句已经扩展了切片的容量。
// 分配比所需的多一倍的空间,以备将来增长。
newSlice := make([]byte, (l+len(data))*2)
// copy 函数是预声明的,适用于任何切片类型。
copy(newSlice, slice)
slice = newSlice
第一行创建了一个更大的切片,名为 "newSlice"。
第二行将 "slice" 的内容复制到 "newSlice"。
然后,"newSlice" 又被克隆回 "slice"。
是的,Go 在这方面感觉有点奇怪,因为不仅内容被复制了,而且 "slice" 现在的容量与 "newSlice" 相同。但这不像 C 语言中的 "指针赋值",因为我们仍然有两个不同的切片实例,一个的变化不会影响另一个。请注意,使用的是赋值运算符 "=",而不是短变量声明运算符 ":=",如 这个 Stack Overflow 的答案 中所述。
实际上所做的是将原始的 "slice" 值和 "0" 赋给了 "newSlice" 的额外位置,但这也是一种浪费,因为 Go 在 make()
语句中已经将它们初始化为 "0"。
这也是第二次浪费,因为紧接着它的循环重新定义了所有这些位置,以及 "data" 中的其余内容。这个 链接 可以帮助理解循环的含义。
所以,这行代码完全没有用,你应该将其删除。
英文:
Just posting this answer for future reference.
That line has no use. The slice's capacity was extended by the statements right above it.
// Allocate double what's needed, for future growth.
newSlice := make([]byte, (l+len(data))*2)
// The copy function is predeclared and works for any slice type.
copy(newSlice, slice)
slice = newSlice
The first line created a bigger slice called "newSlice".
<br>In the second one "slice" had its content copied to "newSlice".
<br>And then, "newSlice" was kind of cloned back to "slice".
Yeah, Go does feel strange about this thing, as not also the content is copied, but "slice" now has the same capacity as "newSlice". But it is not like a "pointer assignment" in C, as we still have two different slice instances and what happens to one doesn't affect the other. Please note the usage of the assignment operator "=" instead of the short variable declaration operator ":=", as noted in this answer in SO
What was actually done was the assignment of the original "slice" values and "0" to the "newSlice" extra positions, but it was also a waste, as Go had already initialized them as "0" in the make()
statement.
It was also a second waste, as the loop right after it redefined all those positions along with the rest of the content in "data". This link may help with the loop meaning.
So, the line has no use at all and you should remove it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论