美文网首页
golang for range 2022-08-31

golang for range 2022-08-31

作者: 9_SooHyun | 来源:发表于2022-08-31 10:20 被阅读0次

核心结论:for range遍历的是拷贝的对象,不是原对象

for range 会拷贝遍历的对象,然后遍历这个拷贝的新对象

  • for range 引用型对象
    map, slice本身是引用型的对象,for range拷贝的就当然只是引用,或者说header。在for range中对map, slice的原对象进行修改,有可能对遍历的结果产生影响,因为原对象和拷贝的、被遍历的对象,指向同一份底层数据

for range map:

// ###for range map###
// You can edit this code!
// Click here and start typing.
package main

import "fmt"

func main() {

    var m1 = make(map[int]int)
    m1[1] = 1
    m1[2] = 2
    m1[3] = 3

    // 可以正常删除当前访问的k v,不影响对map的完整遍历
    for key, val := range m1 {
        fmt.Println(key, val)
        delete(m1, key)
    }
    fmt.Println("final map len: ", len(m1)) // 0

    // for range 内部对map新增k v或者删除k v
    // 新增的k v不一定能被遍历到,因为可能这对kv插入了已经iter过的bucket中
    var m = map[int]int{1: 1, 2: 2, 3: 3}
    for i, _ := range m {
        m[i+3] = i + 3
        fmt.Printf("%d%d ", i, m[i])
    }

}

for range slice1:

// ###for range slice1###
// You can edit this code!
// Click here and start typing.
package main

import "fmt"

func main() {
    // for range s 会拷贝 s 得到s',而 len(s') = 3
    // ele是遍历s'得到的,遍历发生在s'上,因此即使在for range内不断对s append也不会产生无限循环
    s := []int{1, 2, 3}
    for _, ele := range s {
        fmt.Println(ele)
        s = append(s, ele+3)
    }
    fmt.Println(s) // [1 2 3 4 5 6]
}

// 1
// 2
// 3
// [1 2 3 4 5 6]

for range slice2:

// ###for range slice2###
// You can edit this code!
// Click here and start typing.
package main

import "fmt"

func main() {
    // for range s 会拷贝 s 得到s',而 len(s‘) = 5
    // range的对象实际上是s的一份拷贝s',s'和s共同引用一个底层数组
    // 因此即使在for range中对s不断截断,但是s'仍然引用了底层数组的{1, 2, 3, 4, 5}部分
    s := []int{1, 2, 3, 4, 5}
    for _, ele := range s {
        s = s[:len(s)-1] // 截断s
        fmt.Println("current s:", s)
        fmt.Println("visited ele:", ele)
        fmt.Println("---")

    }

}

// current s: [1 2 3 4]
// visited ele: 1
// ---
// current s: [1 2 3]
// visited ele: 2
// ---
// current s: [1 2]
// visited ele: 3
// ---
// current s: [1]
// visited ele: 4
// ---
// current s: []
// visited ele: 5
// ---

  • for range 值型对象
    array是值类型的对象,for range会进行值拷贝。在for range中对array原对象进行修改,不会对遍历的结果产生影响,因为原对象和拷贝的、被遍历的对象,是两个独立的对象
// ###for range slice###
// You can edit this code!
// Click here and start typing.
package main

import "fmt"

func main() {
    // for range s 会拷贝 s 得到s',而 len(s') = 5
    // range的对象实际上是s的一份拷贝s',s'和s是两个独立的数组,不会相互影响
    // 因此即使在for range中对s进行修改,但s'的值不会被影响,遍历得到的仍然是1 2 3 4 5
    s := [5]int{1, 2, 3, 4, 5}
    for index, ele := range s {
        if index < 4 {
            s[index+1] = 100 + s[index]
        }

        fmt.Println("original s:", s)
        fmt.Printf("visited range index: %d, visited range ele: %d\n", index, ele)
        fmt.Println("---")

    }

}

// original s: [1 101 3 4 5]
// visited range index: 0, visited range ele: 1
// ---
// original s: [1 101 201 4 5]
// visited range index: 1, visited range ele: 2
// ---
// original s: [1 101 201 301 5]
// visited range index: 2, visited range ele: 3
// ---
// original s: [1 101 201 301 401]
// visited range index: 3, visited range ele: 4
// ---
// original s: [1 101 201 301 401]
// visited range index: 4, visited range ele: 5
// ---

核心结论:for range遍历的是拷贝的对象,不是原对象

相关文章

  • golang for range 2022-08-31

    核心结论:for range遍历的是拷贝的对象,不是原对象 for range 会拷贝遍历的对象,然后遍历这个拷贝...

  • golang 新手容易遇到的坑

    Golang Range关键字的秘密

  • Learn Golang in Days - Day 11

    Learn Golang in Days - Day 11 要点 Range Go语言中range关键字用于for...

  • golang for,range的坑

    for,range 的k,v变量在整个遍历过程中共用,不能直接进行引用传递,即地址传递,但循环内定义的变量只能为当...

  • Go 学习

    go语言局部变量分配在栈还是堆Golang 垃圾回收剖析go语言坑之for range

  • golang使用指针修改数据引起的血案

    背影知识:golang 中的struct和slice为值赋值, map为引用赋值;range语句for k, v ...

  • golang for range注意事项

    以上代码,对一个 object 数组或 map 进行遍历,对每个元素取地址,循环结束后,a中的4个元素都是 t{4...

  • [golang] for ... range指针的坑

    话不多说,看代码知道输出结果么? 输出结果 for range每次循环使用的是同一个临时变量!每次都是做了一次值拷...

  • golang range的实现原理

    1. 前言 range是Golang提供的一种迭代遍历手段,可操作的类型有数组、切片、Map、channel等,实...

  • Go语言学习笔记(3)

    数组 Golang 中,数组是值类型。 数组的声明 数组的初始化 用 for-range 遍历数组 基本语法: 其...

网友评论

      本文标题:golang for range 2022-08-31

      本文链接:https://www.haomeiwen.com/subject/ijvdnrtx.html