【发布时间】:2020-11-03 15:32:30
【问题描述】:
这看起来很奇怪,在循环中有一个局部变量slice,为每个循环分配了新值,我将该切片附加到全局sliceWrappers。循环完成后,全局切片内的所有值仅包含对该局部切片变量上设置的最后一个值的引用。
代码:
package main
import (
"fmt"
"strconv"
)
func main() {
var sliceWrappers [][]string
initialSlice := append([]string{}, "hi")
initialSlice = append(initialSlice, "there")
// Remove this line and it works fine
initialSlice = append(initialSlice, "I'm")
for i := 0; i < 2; i++ {
slice := append(initialSlice, strconv.Itoa(i))
fmt.Printf("Slice Value : %+v, Initial Value : %+v\n", slice, initialSlice)
sliceWrappers = append(sliceWrappers, slice)
}
for _, sliceWrapper := range sliceWrappers {
fmt.Printf("%+v\n", sliceWrapper)
}
}
实际输出:
Slice Value : [hi there I'm 0], Initial Value : [hi there I'm]
Slice Value : [hi there I'm 1], Initial Value : [hi there I'm]
[hi there I'm 1]
[hi there I'm 1]
预期输出:
Slice Value : [hi there I'm 0], Initial Value : [hi there I'm]
Slice Value : [hi there I'm 1], Initial Value : [hi there I'm]
[hi there I'm 0] <------ This is not happening
[hi there I'm 1]
如果我删除 initialSlice = append(initialSlice, "I'm") 行,那么它可以完美运行。
Slice Value : [hi there 0], Initial Value : [hi there]
Slice Value : [hi there 1], Initial Value : [hi there]
[hi there 0] <------ Works Perfectly
[hi there 1]
我相信这与append有关
append 内置函数将元素追加到切片的末尾。 如果它有足够的容量,则将目标重新切片到 适应新元素。
如果上述条件是造成它的原因,那么循环内打印的initialSlice的值不应该也与slice相同吗?
游乐场 - https://play.golang.org/p/b3SDGoA2Lzv
PS:不幸的是,我为我的代码编写了只有 3 层嵌套的测试用例,它通过了。我现在必须为循环内的切片处理 copy。
【问题讨论】:
-
@Flimzy 不,它不同。在那个问题中,它是关于在范围发生时修改原始切片。这是一个完全不同的循环,我只是尝试将一个值附加到切片并打印它。如果原始切片有 2 个值,则它可以工作,但如果其中有 3 个值,则它会失败。