Golang的for range遍历
生活随笔
收集整理的這篇文章主要介紹了
Golang的for range遍历
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
for range 可以遍歷 ?切片、map等。
for range 遍歷時會首先計算切片的長度,然后創建每個元素的副本。而不是直接返回對該元素的引用,因此如果使用該值變量的地址作為指向每個元素的指針,就會造成錯誤。
在for range中,每次循環,循環變量index和value都會被重新賦值(值拷貝,因此只是副本)。如果在循環體中啟動協程并發,很可能整個循環結束了協程才開始執行,此時所有協程使用的循環變量就有可能已被改寫;如果在循環體中遍歷指針類型,最終實際指向的可能都是同一個地址;
可以通過臨時變量方式或參數傳參方式解決。
存在問題的循環體并發:
package mainimport ("fmt""golang.org/x/sync/errgroup" ) func main() {group := new(errgroup.Group)nums := []int{1, 2, 3,4}for _, num := range nums {group.Go(func() error {fmt.Println("Num:",num)return nil})}// 捕獲errif err := group.Wait(); err != nil {fmt.Println("Get errors: ", err)}else {fmt.Println("Get all num successfully!")} }解決方式一:臨時變量
package mainimport ("fmt""golang.org/x/sync/errgroup" ) func main() {group := new(errgroup.Group)nums := []int{1, 2, 3,4}for _, num := range nums {tmpNum:=numgroup.Go(func() error {fmt.Println("Num:",tmpNum)return nil})}// 捕獲errif err := group.Wait(); err != nil {fmt.Println("Get errors: ", err)}else {fmt.Println("Get all num successfully!")} }解決方式二:參數傳參
errgroup不支持協程傳參,因此使用了goroutine
package mainimport ("fmt""time" )func main() {nums := []int{1, 2, 3, 4}for _, num := range nums {go func(paramNum int) {fmt.Println("Num:", paramNum)return}(num)}time.Sleep(2 * time.Second) }總結
以上是生活随笔為你收集整理的Golang的for range遍历的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面试官扎心一问:Tomcat 在 Spr
- 下一篇: Golang的基本类型、引用类型、复合类