我想从 slice 中删除一些元素,但是它不起作用。
package main
import (
"fmt"
)
func main() {
a := []string{"a", "b", "c"}
for _, command := range a {
if command == "a" || command == "b" || command == "c" {
a = deleteSlice(a, command)
}
}
fmt.Println(a)
}
func deleteSlice(strings []string, str string) []string {
out := strings[:0]
for _, s := range strings {
if s != str {
out = append(out, s)
}
}
return out
}
预期的结果是
[]
,但实际上是[b]
。有人告诉我原因吗?
最佳答案
造成此问题的根本原因是,在deleteSlice()
内部,您没有分配新的支持数组,而是在重新使用传递给它的slice的支持数组,因为您在strings[:0]
中生成了结果。
slice 具有后备阵列。在您的代码中,当初始化包含以下元素的a
时,您在复合文字中会为这种支持数组分配一个单一的分配:
array = ["a", "b", "c"]
因此,首先使用
deleteSlice()
调用"a"
,因此它不会被重新添加。第一次迭代后,支持数组如下所示:array = ["b", "c", "c"]
[ ] <- returned out slice covers this
支持数组仍包含3个元素,但 slice 仅覆盖前2个。
main中的循环进行到下一个迭代(索引= 1),循环遍历的 slice 覆盖整个支持数组(在
for rage
中使用的 slice 仅计算一次!),因此支持数组中索引1的元素现在是“c”。这被传递给deleteSlice()
。 deleteSlice()
删除了"c"
元素,后备数组将不会更改("c"
之后没有要追加的元素):array = ["b", "c", "c"]
[ ] <- returned out slice covers this
并且返回的 slice 的长度为1(支持数组的第一个元素。
main中的循环进行到最后一次迭代:index =2。支持数组在索引2处具有元素“c”,该元素传递给
deleteSlice()
。该元素不包含在 slice 中(该 slice 包含单个["b"]
元素),因此将返回该元素。查看相关问题:
Remove slice element within a for
Remove elements in slice
建议阅读:
The Go Blog: Arrays, slices (and strings): The mechanics of 'append'
The Go Blog: Go Slices: usage and internals
Go Wiki: Slice tricks
关于arrays - 从 slice 中删除元素不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59049074/