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)
}

 

posted @ 2020-11-23 12:27  天之草  阅读(298)  评论(0编辑  收藏  举报