通过两段代码来进行对比:

  1. 开启一个goroutine,在里面对一个nil map进行赋值.并且在这个goroutine里面进行异常捕获.代码如下
func G1() {
	// defer + recover
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("G1 err :", err)
		}
	}()

	// make nil map error
	var myMap map[int]string
	myMap[0] = "hello golang"
}

func main() {
	go G1()

	fmt.Println("MAIN FUNC...")
	time.Sleep(time.Second * 2)
}



console:

MAIN FUNC...
G1 err : assignment to entry in nil map

Process finished with exit code 0

可以看见goroutine里面的异常被捕获了.

2.在main里面写一个异常捕获.代码如下

func G1() {
	// make nil map error
	var myMap map[int]string
	myMap[0] = "hello golang"
}

func main() {
	// defer + recover
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("G1 err :", err)
		}
	}()

	go G1()
	fmt.Println("MAIN FUNC...")
	time.Sleep(time.Second * 2)
}

console:

MAIN FUNC...
panic: assignment to entry in nil map

goroutine 6 [running]:
main.G1()
	/home/ai/go/src/github.com/hyperledger/fabric/scripts/fabric-samples-2.3.0/dataTrade/offer/randdemo/randdemo.go:11 +0x35
created by main.main
	/home/ai/go/src/github.com/hyperledger/fabric/scripts/fabric-samples-2.3.0/dataTrade/offer/randdemo/randdemo.go:22 +0x5b

可以看到main程序里面的异常捕获失败,并且由于goroutine里面的panic导致所有程序奔溃.

总结:在父程序里面的recover不能够捕获子goroutine里面的panic,所以要在每一个goroutine里面做一个异常捕获.