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 来处理通道 

posted @ 2022-09-26 07:56  南昌拌粉的成长  阅读(45)  评论(0编辑  收藏  举报