通过两段代码来进行对比:
- 开启一个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里面做一个异常捕获.