//PANIC//檔案目錄:$GOPATH/src/panic/panic.go/*1 數組訪問越界、null 指標引起panic異常2 panic異常,程式中斷運行,並立即執行goroutine 中defer函數,隨後程式崩潰輸出日誌資訊: panic value、函數呼叫堆疊資訊; panic value通常為某種錯誤資訊,日誌資訊提供足夠診斷工具; panic異常與日誌資訊一併記錄至報告;3 輸入值為空白介面: func panic(v interface{})4 recover輸出值為空白介面: func recover() interface{}5 panic及recover英文解釋 5.1 When panic is called, it immediately stops execution of the //panic異常,程式復原goroutine的棧,執行棧中defer函數 current function and begins unwinding the stack of the goroutine, running any deferred functions along the way. //若復原至棧頂,則程式(goroutine)死掉 If that unwinding reaches the top of the goroutine's stack, the program dies. //recover函數可以重新控制goroutine,並重回正常執行順序 5.2 However, it is possible to use the built-in function recover to regain control of the goroutine and resume normal execution. //recover只能放置defer函數中,因為panic會復原defer函數 A call to recover stops the unwinding and returns the argument passed to panic. Because the only code that runs while unwinding is inside deferred functions, recover is only useful inside deferred functions. 5.3 recover可用於關閉失敗的goroutine而不影響其他goroutine One application of recover is to shut down a failing goroutine inside a server without killing the other executing goroutines.*/package mainimport ( "fmt" "os" "runtime")func main() { //defer函數後panic不會輸出棧資訊 defer func() { p := recover() if p != nil { fmt.Println("panic value: ", p) } }() //添加列印棧資訊函數可輸出棧資訊 defer printStack() f(3)}func f(x int) { fmt.Printf("f(%d)\n", x+0/x) // panics if x == 0 defer fmt.Printf("defer %d\n", x) f(x - 1)}func printStack() { var buf [4096]byte n := runtime.Stack(buf[:], false) os.Stdout.Write(buf[:n])}//RECOVER//檔案目錄:$GOPATH/src/recover/panicRecv.go/*1 defer函數調用recover, defer程式正常退出或panic 執行: defer func(){ if p:= recover(); p != nil{};}() 1.1 recover使程式從panic恢複,並返回panic value 1.2 導致panic異常的函數不會繼續運行,但正常返回 1.3 未發生panic時調用recover,recover會返回nil2 對panic value做特殊標記,當recover收到的p值為標記 值則處理,其他情況繼續異常: defer func(){ switch p := recover(); p{ //無panic異常 case nil: //panic value為標記值,執行recover恢複+處理語句 case bailout{}: err := fmt.Errorf("the error is ...") //panic異常且不是標記值繼續panic default: panic(p) } }()*/package mainimport "fmt"func t1(i int) (j int) { defer func() { if p := recover(); p != nil { i = 1 - i j = 1 } }() if i <= 0 { panic("please input a int >0") } j = i return j //return uint(i)}func main() { fmt.Println(t1(-1))}
78 次點擊 ∙ 1 贊