前言

``````    list := []*Demo{{"a"}, {"b"}}
for _, v := range list {
go func() {
fmt.Println("name="+v.Name)
}()
}

type Demo struct {
Name string
}``````

``````name=b
name=b``````

``````name=a
name=b``````

坑一

``````    list := []*Demo{{"a"}, {"b"}}
for _, v := range list {
temp:=v
go func() {
fmt.Println("name="+temp.Name)
}()
}``````

``````    list := []*Demo{{"a"}, {"b"}}
for _, v := range list {
go func(temp *Demo) {
fmt.Println("name="+temp.Name)
}(v)
}``````

坑二

``````    list2 := []Demo{{"a"}, {"b"}}
var alist []*Demo
for _, test := range list2 {
alist = append(alist, &test)
}
fmt.Println(alist[0].Name, alist[1].Name)``````

``b b``

``````    list2 := []Demo{{"a"}, {"b"}}
var alist []Demo
for _, test := range list2 {
alist = append(alist, test)
}
fmt.Println(alist[0].Name, alist[1].Name)``````
``````addr=0xc000010240
a b``````

``````    list2 := []Demo{{"a"}, {"b"}}
var alist []*Demo
for _, test := range list2 {
temp := test
alist = append(alist, &temp)
}
fmt.Println(alist[0].Name, alist[1].Name)``````

defer 的坑

`for` 循环 + `defer` 也是组合坑（虽然不推荐这么用），还是先来看个例子：

``````
// demo1
func main() {
a := []int{1, 2, 3}
for _, v := range a {
defer fmt.Println(v)
}
}

// demo2
func main() {
a := []int{1, 2, 3}
for _, v := range a {
defer func() {
fmt.Println(v)
}()
}
}``````

``````//demo1
3
2
1
//demo2
3
3
3``````

`demo1`的结果很好理解，`defer` 可以理解为将执行语句放入到栈中，所以呈现的结果是先进后出。

`demo2`中，由于是闭包，闭包对变量 v 持有的是引用，所以在最终延迟执行时 v 已经被最后一个值赋值，所以打印出来都是相同的。

``````    for _, v := range a {
defer func(v int) {
fmt.Println(v)
}(v)
}``````

总结

https://github.com/golang/go/wiki/CommonMistakes#using-reference-to-loop-iterator-variable