首页  >  文章  >  后端开发  >  为什么附加到 Go 切片有时会修改原始切片?

为什么附加到 Go 切片有时会修改原始切片?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-10-31 17:00:30722浏览

Why does appending to a Go slice sometimes modify the original slice?

Golang Append 的切片分配行为

在 Go 中,当追加到切片时,有必要了解分配行为以确保高效处理。

根据内置API文档,当现有切片容量不足时,append()函数会重新分配数据并将数据复制到新的数组块中。这引发了关于切片描述符和从append()返回的切片的性质的问题。

在提供的用于生成组合的递归算法中,append()函数用于增量构造切片。但是,据观察,从 AddOption 函数通过通道发送的切片在发送后会被修改。这与append()应该返回一个新切片的期望相矛盾。

要解决这种明显的差异,必须澄清切片数据类型与其底层表示之间的区别。切片描述符由两个整数(长度和容量)和一个指向实际数据的指针组成。当append()创建一个新切片时,它会生成一个新的切片描述符,但保留与原始切片相同的数据指针。因此,对任一切片描述符所做的更改都会影响两个切片。

为了说明这一点,请考虑以下代码片段:

<code class="go">s := make([]int, 0, 5)
s = append(s, []int{1, 2, 3, 4}...)

a := append(s, 5)
fmt.Println(a)  // [1 2 3 4 5]

b := append(s, 6)
fmt.Println(b)  // [1 2 3 4 6]
fmt.Println(a)  // [1 2 3 4 6]</code>

最初,s 的容量为 5,并使用 make 构造()。 append() 用于将另一个切片的元素添加到 s 中。然后,使用带有不同元素的 s 上的append() 创建两个新切片a 和b。观察输出,a和b都包含相同的数据,表明它们共享相同的数据指针。这演示了上述行为。

为了确保高效的切片操作,理解append() 的这种分配行为至关重要。如果现有切片的容量足够,append()将直接操作现有数据指针,从而提高效率。

以上是为什么附加到 Go 切片有时会修改原始切片?的详细内容。更多信息请关注PHP中文网其他相关文章!

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