go协程全局变量和局部变量


本文摘自网络,作者,侵删。

大家可能经常会用到类似如下代码片段:

package main

import (   "fmt"
   "sync"
   "time")

func main() {
   sli := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
   wg := sync.WaitGroup{}   for k, v := range sli {
      wg.Add(1)
      go func() {
         time.Sleep(time.Second)
         fmt.Println(k, v)
         wg.Done()
      }()
   }
   wg.Wait()
}

打印输出:

9 99 99 99 99 99 99 99 99 99 9

结果是不是和想象的不一样?,主要原因出在协程这里,如果不使用协程,直接使用串行的方式,结果结合预期一致,比如:

package main

import (   "fmt"
   "time")

func main() {
   sli := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}   for k, v := range sli {
      func() {
         time.Sleep(time.Second)
         fmt.Println(k, v)
      }()
   }
}

打印输出:

0 01 12 23 34 45 56 67 78 89 9

那为什么上面使用携程的输出都是相同值?我们来解读下:
其中 k, v 是迭代变量,每次迭代都会给 k, v 赋值新的值,并且多个协程又同时调用了 k, v ,所以结果就串了,那携程怎么解决?解决方式我们可以定义一个局部变量。

package main

import (   "fmt"
   "sync"
   "time")

func main() {
   sli := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
   wg := sync.WaitGroup{}   for k, v := range sli {
      wg.Add(1)
      k1 := k
      v1 := v
      go func() {
         time.Sleep(time.Second)
         fmt.Println(k1, v1)
         wg.Done()
      }()
   }
   wg.Wait()
}

k1, v1 是局部变量,每次循环,循环体内是不共享的,这也是为什么可以这样声明变量(k1 := k)。

或者通过传参的方式来固定下来,比如像下面这样:

package main

import (   "fmt"
   "sync"
   "time")

func main() {
   sli := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
   wg := sync.WaitGroup{}   for k, v := range sli {
      wg.Add(1)

      go func(k, v interface{}) {
         time.Sleep(time.Second)
         fmt.Println(k, v)
         wg.Done()
      }(k, v)
   }
   wg.Wait()
}

这样输出就正常,比如输出如下:

0 05 52 23 34 41 19 96 68 87 7

 


本文来自:51CTO博客

感谢作者:mb6004f7ec10a08

查看原文:go协程全局变量和局部变量

相关阅读 >>

Golang】make和new区别,append

Goland解析json获取指定字段内容

记录Go的循环遍历使用小坑

聊聊dapr的fswatcher

Go从学会到学废】(一) 下载、安装、配置

redis Go语言与redis数据库交互

Go - 实现项目内链路追踪(二)

手撸Golang 基本数据结构与算法 网页排名/pagerank,随机游走

完全掌握Go的pprof使用方法

手撸Golang 基本数据结构与算法 图的最短路径  狄克斯特拉算法

更多相关阅读请进入《Go》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...