经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Go语言 » 查看文章
go协程全局变量和局部变量
来源:cnblogs  作者:周伯通的麦田  时间:2021/1/11 9:37:56  对本文有异议

原文链接:http://www.zhoubotong.site/post/19.html

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

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. "time"
  6. )
  7. func main() {
  8. sli := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
  9. wg := sync.WaitGroup{}
  10. for k, v := range sli {
  11. wg.Add(1)
  12. go func() {
  13. time.Sleep(time.Second)
  14. fmt.Println(k, v)
  15. wg.Done()
  16. }()
  17. }
  18. wg.Wait()
  19. }

打印输出:

  1. 9 9
  2. 9 9
  3. 9 9
  4. 9 9
  5. 9 9
  6. 9 9
  7. 9 9
  8. 9 9
  9. 9 9
  10. 9 9

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

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

打印输出:

  1. 0 0
  2. 1 1
  3. 2 2
  4. 3 3
  5. 4 4
  6. 5 5
  7. 6 6
  8. 7 7
  9. 8 8
  10. 9 9

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

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. "time"
  6. )
  7. func main() {
  8. sli := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
  9. wg := sync.WaitGroup{}
  10. for k, v := range sli {
  11. wg.Add(1)
  12. k1 := k
  13. v1 := v
  14. go func() {
  15. time.Sleep(time.Second)
  16. fmt.Println(k1, v1)
  17. wg.Done()
  18. }()
  19. }
  20. wg.Wait()
  21. }

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

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

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. "time"
  6. )
  7. func main() {
  8. sli := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
  9. wg := sync.WaitGroup{}
  10. for k, v := range sli {
  11. wg.Add(1)
  12. go func(k, v interface{}) {
  13. time.Sleep(time.Second)
  14. fmt.Println(k, v)
  15. wg.Done()
  16. }(k, v)
  17. }
  18. wg.Wait()
  19. }

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

  1. 0 0
  2. 5 5
  3. 2 2
  4. 3 3
  5. 4 4
  6. 1 1
  7. 9 9
  8. 6 6
  9. 8 8
  10. 7 7

 

原文链接:http://www.cnblogs.com/phpper/p/14258874.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号