关于go的闭包与shadow

zackzhangkai · · 983 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

比如要实现从0到9的打印,需求很简单 原则1: 协程是共享函数的变量的,换句话说:在一个函数中,如果有一个协程,这个协程是可以使用这个函数的变量的。 如下这个执行有问题 ```go func shadow() { for i := 0; i < 10; i++ { go func() { fmt.Println(i) //Question1: 为什么i取不到上面i的值?不是说好协程共享函数的变量的吗,现在怎么背叛我了? }() } time.Sleep(time.Second) } ``` 需要改成如下才行: ```go func shadow() { for i := 0; i < 10; i++ { go func(i int) { fmt.Println(i) }(i) //Question2: 问题跟上面类型,背叛了原则1。因它取不到 i的值。 } time.Sleep(time.Second) } ``` 或是,如下也是可以的 ```go func scope() { for i := 0; i < 10; i++ { i := i //需要加上这个语句,才会从0打印到9;否则打印的不是预期 go func() { fmt.Println(i) }() } time.Sleep(time.Second) } ``` 下面这个示例是对*原则1*的证明,协程确实是共享函数的变量的。 ```go c := make(chan int) go func() { time.Sleep(time.Second * 1) c <- 10 //Question3: 像这里的c它其实是go func外部的变量。但是协程里面,为什么这里又不是个func{}这个函数中的局部变量?为什么这里不需要通过传参的形式来实现? close(c) }() for { select { default: fmt.Printf("%v No Output, now is default\n", time.Now().Format(fmat)) case x, ok := <-c: fmt.Printf("%v, Now step into chan, x:%v, ok:%v\n", time.Now().Format(fmat), x, ok) time.Sleep(time.Second * 5) } } ``` 但是为什么在for range中协程取不到函数的变量呢?

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

983 次点击  
加入收藏 微博
2 回复  |  直到 2020-07-25 10:30:32
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传