Go異常處理


首先很抱歉,由於搬家,最近太多事情要處理,導致文章更新比較慢。

這篇文章,我們講Go中的異常處理。

Go提供了兩個內置函數 panic()和recover()用於異常處理。

Go中,對異常處理的整體原則是:多用errors包,少用panic。

對於可預見的錯誤,比如網絡連接失敗等,一般都使用errors,只有重大錯誤才會使用panic。

 

記住一個大原則:panic會導致程序直接掛掉,除非調用了recover方法。

 

在函數內部調用 panic 會立即終止當前函數的執行,由當前調用棧逐層返回,一直到最頂層的 main 函數或是被某一層的 recover 捕捉到。

 

看例子:

package main

 

import (

"fmt"

)

 

func main() {

fmt.Println("Start main")

sub()

fmt.Println("End main")

}

 

func sub() {

fmt.Println("Before panic")

panic("golang_everyday")

fmt.Println("After panic")

}

執行結果:

Start main

Before panic

panic: golang_everyday

 

goroutine 1 [running]:

main.sub()

/Users/baiyuxiong/go/src/baiyuxiong.com/demo/panic.go:18 +0x124

main.main()

/Users/baiyuxiong/go/src/baiyuxiong.com/demo/panic.go:10 +0xdf

 

goroutine 2 [runnable]:

runtime.forcegchelper()

/usr/local/go/src/runtime/proc.go:90

runtime.goexit()

/usr/local/go/src/runtime/asm_amd64.s:2232 +0x1

 

goroutine 3 [runnable]:

runtime.bgsweep()

/usr/local/go/src/runtime/mgc0.go:82

runtime.goexit()

/usr/local/go/src/runtime/asm_amd64.s:2232 +0x1

 

goroutine 4 [runnable]:

runtime.runfinq()

/usr/local/go/src/runtime/malloc.go:712

runtime.goexit()

/usr/local/go/src/runtime/asm_amd64.s:2232 +0x1

exit status 2

可以看到,panic之后,程序停止繼續執行,一層層的退出直到main,退出了整個程序,然后打印了堆棧信息。

如果我們在sub函數中,使用defer進行recover:

package main

 

import (

"fmt"

)

 

func main() {

fmt.Println("Start main")

sub()

fmt.Println("End main")

}

 

func sub() {

defer handler()

 

fmt.Println("Before panic")

panic("golang_everyday")

fmt.Println("After panic")

}

 

func handler() {

if err := recover(); err != nil {

fmt.Println("recover msg: ", err)

} else {

fmt.Println("recover ok")

}

}

 

執行結果:

Start main

Before panic

recover msg: golang_everyday

End main

可以看到,sub函數沒有執行完,panic后執行了defer就返回到上層main函數了,但是main函數執行結束了。

這是因為recover阻止了異常的繼續傳播。他將panic限制在了一定的范圍內。

 

這就像屋子里丟了一炸彈(panic產生了),本來所有人都要掛掉的(panic傳遞到main,整個程序退出),但是有一個叫recover的小伙子非常勇敢,duang!!!抱到炸彈上去了,損失就控制在一定范圍內了,如果這小伙子越早的抱到炸彈,受傷的人就會越少。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM