go for循环陷阱(类似c++的迭代器失效)
迭代器自身是不知道是否“失效”的,它本质上只是一个迭代对象的包装。
我对“失效”的理解是,在创建一次迭代的开始时,这个迭代器应该迭代的所有元素就已经确定了,换句话说,有一个确定的迭代序列;如果说在迭代的过程中出现了与已经确定的迭代序列不同的序列,那么就可能会认为这个迭代器失效了。
具体到不同的容器,迭代器失效的情况也是不一样的,会存在一些只会使指向容器中某个特定元素失效的情况,也有可能使指向所有元素的迭代器都失效。
func main() { // 错误例子: slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} for i, value := range slice { if value%3 == 0 { // remove 3, 6, 9 fmt.Println(i, value, len(slice)) slice = append(slice[:i], slice[i+1:]...) // 删除后,slice会立即变,内存都可能改变了,但是i依然是旧的,所以会造成越界 } } fmt.Printf("%vn", slice) //// 解决办法: 把需要保留的放到最左边,最后截取切片就ok了 //slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} //k := 0 //for _, v := range slice { // if v%3 != 0 { // slice[k] = v // k++ // } //} //slice = slice[:k] //fmt.Println(slice) }