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.MustComplietemplate.Must;當正則表達式或模板中轉入的轉換字符串導致錯誤時,這些函數會 panic。

不能隨意地用 panic 中止程序,必須盡力補救錯誤讓程序能繼續執行。

鏈接

results matching ""

    No results matching ""