比如要实现从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中协程取不到函数的变量呢?
有疑问加站长微信联系(非本文作者)