go for-range中的循環變量


測試的時候發現一個有意思的地方,就是go始終利用同一塊內存來接收集合中的一個值,只是在每次循環的時候重新賦值而已。

 

package main

import (
    "fmt"
    "time"
)

func main() {
    ii := []int{1, 2, 3, 4, 5}

    for idx, i := range ii {
        fmt.Printf("[%d]: [%d]@ %p -->%p\n", idx, i, &i, &(ii[idx])) //結論是,&i始終不變!
    }

    uu := []user{user{1, "aaa"}, user{2, "bbb"}, user{3, "ccc"}, user{4, "ddd"}}

    for idx, i := range uu {
        fmt.Printf("[%d]: [%v]@ %p -->%p\n", idx, i, &i, &(uu[idx])) //結論是,&i始終不變!而且,值正常,說明空間是重復利用。
    }

    //怎么驗證呢?需要監控數據的變化,反射嗎?不用,goroutine時刻對比就行 - 雖然性能極低
    var u *user
    go func() {
        id := u.id
        name := u.name
        for {
            if id != u.id {
                fmt.Println("id changed!", id, "to", u.id) //通過這個的變化,來觀察是否有清零過程 - 結論是沒有
                id = u.id
            }
            if name != u.name {
                fmt.Println("name changed!", name, "to", u.name) //通過這個的變化,來觀察是否有清零過程 - 結論是沒有
                name = u.name
            }
        }
    }()
    for idx, i := range uu {
        if idx == 0 {
            u = &i
        }
        fmt.Printf("[%d]: [%v]@ %p -->%p\n", idx, i, &i, &(uu[idx])) //結論是,&i始終不變!而且,值正常,說明空間是復利用。
        time.Sleep(time.Second)
    }
}

type user struct {
    id int
    name string
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM