13.2 運行時異常和 panic
當發生像數組下標越界或類型斷言失敗這樣的運行錯誤時,Go 運行時會觸發運行時 panic,伴隨着程序的崩潰拋出一個 runtime.Error
接口類型的值。這個錯誤值有個 RuntimeError()
方法用於區別普通錯誤。
panic
可以直接從代碼初始化:當錯誤條件(我們所測試的代碼)很嚴苛且不可恢復,程序不能繼續運行時,可以使用 panic
函數產生一箇中止程序的運行時錯誤。panic
接收一個做任意類型的參數,通常是字符串,在程序死亡時被打印出來。Go 運行時負責中止程序並給出調試信息。在示例 13.2 panic.go 中闡明瞭它的工作方式:
package main
import "fmt"
func main() {
fmt.Println("Starting the program")
panic("A severe error occurred: stopping the program!")
fmt.Println("Ending the program")
}
輸出如下:
Starting the program
panic: A severe error occurred: stopping the program!
panic PC=0x4f3038
runtime.panic+0x99 /go/src/pkg/runtime/proc.c:1032
runtime.panic(0x442938, 0x4f08e8)
main.main+0xa5 E:/Go/GoBoek/code examples/chapter 13/panic.go:8
main.main()
runtime.mainstart+0xf 386/asm.s:84
runtime.mainstart()
runtime.goexit /go/src/pkg/runtime/proc.c:148
runtime.goexit()
---- Error run E:/Go/GoBoek/code examples/chapter 13/panic.exe with code Crashed
---- Program exited with code -1073741783
一個檢查程序是否被已知用戶啓動的具體例子:
var user = os.Getenv(“USER”)
func check() {
if user == “” {
panic(“Unknown user: no value for $USER”)
}
}
可以在導入包的 init() 函數中檢查這些。
當發生錯誤必須中止程序時,panic
可以用於錯誤處理模式:
if err != nil {
panic(“ERROR occurred:” + err.Error())
}
Go panicking:
在多層嵌套的函數調用中調用 panic,可以馬上中止當前函數的執行,所有的 defer 語句都會保證執行並把控制權交還給接收到 panic 的函數調用者。這樣向上冒泡直到最頂層,並執行(每層的) defer,在棧頂處程序崩潰,並在命令行中用傳給 panic 的值報告錯誤情況:這個終止過程就是 panicking。
標準庫中有許多包含 Must
前綴的函數,像 regexp.MustComplie
和 template.Must
;當正則表達式或模板中轉入的轉換字符串導致錯誤時,這些函數會 panic。
不能隨意地用 panic 中止程序,必須盡力補救錯誤讓程序能繼續執行。
鏈接
- 目錄
- 上一節:錯誤處理
- 下一節:從 panic 中恢復(Recover)