首页 >后端开发 >Golang >为什么在 Go 中附加到循环中的切片会产生意外结果?

为什么在 Go 中附加到循环中的切片会产生意外结果?

DDD
DDD原创
2024-11-03 04:57:311179浏览

Why Does Appending to a Slice in a Loop Produce Unexpected Results in Go?

切片上追加操作的意外行为

在 Go 中,在循环迭代期间将元素追加到切片然后创建新元素时,可能会出现意外行为根据结果​​进行切片。此行为源于对引用进行切片的底层数组。

考虑以下代码:

<code class="go">func create(iterations int) []int {
    a := make([]int, 0)
    for i := 0; i < iterations; i++ {
        a = append(a, i)
    }
    return a
}</code>

如果我们调用 create(11) 并将结果分配给 i,我们期望每个后续追加操作 (j :=append(i, 100)、g :=append(i, 101) 和 h :=append(i, 102)) 创建具有不同值的新切片。然而,观察到的行为是,这些新切片的最后一个元素始终为 102,无论其索引如何。

发生这种情况是因为所有追加都修改相同的底层数组。将元素附加到切片会更改长度并可能导致数组的重新分配。分配新数组时,所有先前对旧数组的引用都将变得无效。

但是,切片文字的行为符合预期,因为如果追加超出后备数组的容量,则始终会分配新数组。

惯用方法

为了确保基于现有切片创建多个新切片时的可预测行为,惯用方法是在附加元素之前复制切片:

<code class="go">func makeFromSlice(sl []int) []int {
    result := make([]int, len(sl))
    copy(result, sl)
    return result
}</code>

通过执行复制,我们创建一个新的支持数组,并确保对结果切片所做的更改不会影响原始切片。

以上是为什么在 Go 中附加到循环中的切片会产生意外结果?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn