0%

golang闭包的坑

1. 循环内goroutine使用闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
func main() {
s := []string{"a", "b", "c"}
for _, v := range s {
go func() {
fmt.Println(v)
}()
}

time.Sleep(time.Second)
}


// c c c

改进:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func main() {                
s := []string{"a", "b", "c"}
for _, v := range s {
go func(v string) {
fmt.Println(v)
}(v)
}
}
// a b c


func main() {
s := []string{"a", "b", "c"}
for _, v := range s {
vv := v
go func() {
fmt.Println(vv)
}()
}

time.Sleep(time.Second)
}
// a b c

2. 循环内闭包函数列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func test() []func() {
var s []func()

for i := 0; i < 3; i++ {
s = append(s, func() {
fmt.Println(&i, i)
})
}

return s
}
func main() {
for _, f := range test() {
f()
}
}

/*
0x1400001a0f8 3
0x1400001a0f8 3
0x1400001a0f8 3
*/

改进:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func test() []func() {
var s []func()

for i := 0; i < 3; i++ {
x := i
s = append(s, func() {
fmt.Println(&x, x)
})
}

return s
}
func main() {
for _, f := range test() {
f()
}
}

/*
0x1400001a0f8 0
0x1400001a100 1
0x1400001a108 2
*/

3. defer延迟调用闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func main() {
x, y := 1, 2

defer func(x int) {
fmt.Println("defer", "x", x, "y", y) // y是闭包引用
}(x)

x += 100
y += 100
fmt.Println("main", "x", x, "y", y)
}



/*
main x 101 y 102
defer x 1 y 102
*/
给作者打赏,可以加首页微信,咨询作者相关问题!