在遍历slice的时候删除其元素导致的panic “slice bounds out of range”
//删除slice中的3,6,9
func test1() {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
for i, n := range slice {
if n%3 == 0 {
slice = append(slice[:i], slice[i+1:]...)
}
}
fmt.Printf("%v\n", slice)
}
运行后报了一个panic出来:
panic: runtime error: slice bounds out of range
goroutine 1 [running]:
panic(0x5189c0, 0xc082002040)
D:/Go/src/runtime/panic.go:464 +0x3f4
main.test4()
E:/Code/go/hello.go:79 +0x395
main.main()
E:/Code/go/hello.go:16 +0x20
exit status 2
是不是这种情况不应该使用这种方式来删除元素?slice = append(slice[:i], slice[i+1:]...)
如果不是应该用什么方式来删除呢?
共 7 个回复
heimeil
range里面就不应该再修改原始slice了,可以另外新建一个slice
luxor
s0 := []int{1,2,3}
for range等价于
s1 := s0
for i:=0;i<s1.len;i++{}
for 循环中s0删除后,s0.len也变小了,但s1.len还是原来的值,自然就越界了
mnhkahn
很有意思,map就支持在遍历的时候删除
nuokesasi
map是按key,slice是按索引 @mnhkahn
ayanmw
加一个goto吧。这是我想到的最容易的办法了。
1.C++ STL的map支持修改迭代器,但是golang的range 不算迭代器,怎么修改呢?
ayanmw
我有想到了一种方案,就是 将需要删除的元素放到最后,然后最后一次性删除,减少遍历次数;
代码如下:
缺点就是顺序变了,不过这个应该不是什么大问题的吧。
xixi~
#4 4楼牛牛的