Skip to content

Commit

Permalink
update discuss 2018-05-21
Browse files Browse the repository at this point in the history
  • Loading branch information
t00361654 committed May 22, 2018
1 parent c483d26 commit d871b27
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions discuss/2018-05-21-using-goroutines-on-loop-iterator-variables.md
Expand Up @@ -26,6 +26,50 @@ time.Sleep(time.Second)

延伸出来的知识点:惰性求值和闭包。

解答:
根据问题的描述推断出是闭包的特性,通过Google检索关键字*glang faq loop closure*可找到官方的[faq](https://golang.org/doc/faq#closures_and_goroutines),里面有详细的解释,并提醒了用户可以通过__go vet__命令来检查程序中类似的问题。

最后官方的faq还给出了针对这个问题的两种解决方法。其中第一种方法很好理解,就是把变量v的值通过参数的形式传递给goroutine,因为go中func的参数都是值传递,所以这样就在goroutine启动是获得了当前v变量的值。
```go
for _, v := range values {
go func(u string) {
fmt.Println(u)
done <- true
}(v)
}
```
第二种方法是更巧妙地通过一个赋值语句来解决的。
```go
for _, v := range values {
v := v // create a new 'v'.
go func() {
fmt.Println(v)
done <- true
}()
}
```
如果没有明白其中的原理,只要自己把赋值前后变量v的内存地址打印出来就明白了,在赋值后新的v变量实际上是在内存中开辟了一个新的空间并保存了当前v变量的值,两个v变量并不是指向相同的内存地址。
```go
for _, v := range values {
fmt.Printf("Before assignment:%p\n", &v)
v := v
fmt.Printf("After assignment:%p\n", &v)
go func() {
fmt.Println(v)
done <- true
}()
}
// Output:
// Before assignment:0xc04206c080
// After assignment:0xc04206c090
// Before assignment:0xc04206c080
// After assignment:0xc04206c0a0
// Before assignment:0xc04206c080
// After assignment:0xc04206c0b0
```



## 2. []int 转 []int32 有没有什么好办法?

?
Expand Down

0 comments on commit d871b27

Please sign in to comment.