Go 删除切片中的每个元素
当我尝试循环通过一个切片并按顺序删除每个元素以打印其余元素时,我遇到了一些意想不到的行为,使用建议的Delete方法。例如,当我尝试循环一个包含字母Go 删除切片中的每个元素,go,Go,当我尝试循环通过一个切片并按顺序删除每个元素以打印其余元素时,我遇到了一些意想不到的行为,使用建议的Delete方法。例如,当我尝试循环一个包含字母[ab C]的切片时,我希望输出是[bc],[ac],[ab],顺序如下: 方法1 package main import "fmt" func main() { a := []string {"A", "B", "C"} for i, _ := range a { fmt.Println(append(a[:i]
[ab C]
的切片时,我希望输出是[bc]
,[ac]
,[ab]
,顺序如下:
方法1
package main
import "fmt"
func main() {
a := []string {"A", "B", "C"}
for i, _ := range a {
fmt.Println(append(a[:i], a[i+1:]...))
}
}
然而,这里的输出令我惊讶。它输出三次[bc]
通过以下操作,我最终获得了预期的行为:
方法2
package main
import "fmt"
func main() {
a := []string {"A", "B", "C"}
for i, _ := range a {
result := make([]string, 0)
result = append(result, a[:i]...)
result = append(result, a[i+1:]...)
fmt.Println(result)
}
}
方法1中出现意外行为的原因是什么?除了方法2之外,还有其他更好的方法吗?查看第一次迭代后发生的情况:
package main
import "fmt"
func main() {
a := []string{"A", "B", "C"}
x := append(a[:0], a[1:]...)
fmt.Println(a)
fmt.Println(x)
}
给予
[B C C]
[B C]
看
接下来的两个迭代是相似的。试一试。因为“what”实际上是在用新元素更新片段。它返回一个“新”片只是因为它可能由于内存重新分配而不得不重新定位原始片。因此,在示例代码中,您实际上是在每次调用append
时更改a
的内容。(golang博客文章的“附加:示例”部分提供了一个很好的概述)
至于“如何”,我的尝试是:
package main
import "fmt"
func main() {
a := []string {"A", "B", "C"}
for i, _ := range a {
result := make([]string, i, len(a)-1)
copy(result, a[:i])
result = append(result, a[i+1:]...)
fmt.Println(result)
}
}
使用长度和容量初始化result
,以及使用copy
而不是两次append
s尝试减少所需的内存重新分配次数。如果不想进行额外分配,请尝试只交换值,如图所示:
请注意,这假设您可以洗牌列表内容。
如果没有,只需在循环之前复制列表一次,并执行以下操作
package main
import "fmt"
func main() {
set := []string{"a", "b", "c"}
for i := range set {
set[0], set[i] = set[i], set[0]
fmt.Println(set[1:])
}
}
输出:
[b c]
[a c]
[a b]
无法从append分配值通常是一个错误mistake@JimB这是OP的一个要求。基本上就是打印一个切片,每次按顺序删除一个元素。OP:这样的切片索引和速记是不可能的。您必须更详细一点。您可以跳过迭代0中的交换,因为将x[0]与x[0]交换是不可操作的。这对发生意外行为的原因给出了最佳解释,也给出了可接受的替代方案。不过,我更喜欢@jimt提供的解决方案。