- for循环错误反例:
func main() {
in := []int{1, 2, 3, 4, 5}
out := make([]*int, 0)
for _, v := range in {
//v := v 打开注释即正确
out = append(out, &v)
}
fmt.Println("res:", *out[0], *out[1], *out[2])
}
期望结果:1,2,3
实际结果:5,5,5
原因:range出来的v是同一个地址,最后都指向了5
解决方案:打开注释,分配新地址再赋值
- for循环错误反例2:
package main
import (
"fmt"
"sync"
)
func main() {
var mutex sync.Mutex
type ABC struct {
Aa int
}
persons := make([]ABC, 10)
for i, p := range persons {
mutex.Lock()
defer mutex.Unlock()
p.Aa = 2
fmt.Println("count:", i)
}
}
大家会习惯在上锁后直接defer解锁,如果defer写到了for里面,运行就会出错啦。fatal error: all goroutines are asleep - deadlock!
两种解决方案,一种for里面不要用defer。另一种可以for里面设计个匿名函数,如下:
package main
import (
"fmt"
"sync"
)
func main() {
var mutex sync.Mutex
type ABC struct {
Aa int
}
persons := make([]ABC, 10)
for i, p := range persons {
func() {
mutex.Lock()
defer mutex.Unlock()
p.Aa = 2
fmt.Println("count:", i)
}()
}
}
本文讨论了两个for循环中的常见错误:范围变量共享导致的结果不一致,以及在并发环境下如何避免deadlock。通过实例解析了问题原因并提供了两种解决方案,包括使用指针赋值和匿名函数来管理锁操作。

61

被折叠的 条评论
为什么被折叠?



