golang常见编程错误集
一、append是深拷贝,
func main() { a := []int{7, 8, 9} fmt.Printf("%+v\n", a) ap(a) fmt.Println("==", a) app(a) fmt.Println("-a-a", a) } func ap(a []int) { a = append(a, 10) } func app(a []int) { a[0] = 1 }
二、waitgroup用法
package main import ( "fmt" "runtime" "sync" ) func main() { runtime.GOMAXPROCS(1) wg := sync.WaitGroup{} wg.Add(20) for i := 0; i < 10; i++ { go func() { fmt.Println("i=", i) wg.Done() }() } for i := 0; i < 10; i++ { go func(i int) { fmt.Println("i=", i) wg.Done() }(i) } wg.Wait() }
三、通道误用示例
// demo1 通道误用导致的bug func demo1() { wg := sync.WaitGroup{} ch := make(chan int, 10) for i := 0; i < 10; i++ { ch <- i } close(ch) wg.Add(3) for j := 0; j < 3; j++ { go func() { for { task := <-ch // 这里假设对接收的数据执行某些操作 fmt.Println(task) } wg.Done() }() } wg.Wait() }
解析:将上述代码编译执行后,匿名函数所在的 goroutine 并不会按照预期在通道被关闭后退出。因为task := <- ch
的接收操作在通道被关闭后会一直接收到零值,而不会退出。此处的接收操作应该使用task, ok := <- ch
,通过判断布尔值ok
为假时退出;或者使用select 来处理通道