·  阅读 4755

# 前言

``````	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)
}
``````

# 总结

github.com/golang/go/w… 只是大部分人估计都没去看过，这事之后我也得花时间好好阅读下。

ps: 最近掘金在投人气作者，放个链接佛系拉票。

rank.juejin.cn/rank/2021/8…