Go 沒有像 Java 和 .NET 那樣的 try/catch
異常機(jī)制:不能執(zhí)行拋異常操作。但是有一套 defer-panic-and-recover
機(jī)制(參見 13.2-13.3 節(jié))。
Go 的設(shè)計者覺得 try/catch
機(jī)制的使用太泛濫了,而且從底層向更高的層級拋異常太耗費(fèi)資源。他們給 Go 設(shè)計的機(jī)制也可以 “捕捉” 異常,但是更輕量,并且只應(yīng)該作為(處理錯誤的)最后的手段。
Go 是怎么處理普通錯誤的呢?通過在函數(shù)和方法中返回錯誤對象作為它們的唯一或最后一個返回值——如果返回 nil,則沒有錯誤發(fā)生——并且主調(diào)(calling)函數(shù)總是應(yīng)該檢查收到的錯誤。
永遠(yuǎn)不要忽略錯誤,否則可能會導(dǎo)致程序崩潰??!
處理錯誤并且在函數(shù)發(fā)生錯誤的地方給用戶返回錯誤信息:照這樣處理就算真的出了問題,你的程序也能繼續(xù)運(yùn)行并且通知給用戶。panic and recover
是用來處理真正的異常(無法預(yù)測的錯誤)而不是普通的錯誤。
庫函數(shù)通常必須返回某種錯誤提示給主調(diào)(calling)函數(shù)。
在前面的章節(jié)中我們了解了 Go 檢查和報告錯誤條件的慣有方式:
產(chǎn)生錯誤的函數(shù)會返回兩個變量,一個值和一個錯誤碼;如果后者是 nil 就是成功,非 nil 就是發(fā)生了錯誤。
下面這段來自 pack1 包的代碼 Func1 測試了它的返回值:
if value, err := pack1.Func1(param1); err != nil {
fmt.Printf("Error %s in pack1.Func1 with parameter %v", err.Error(), param1)
return // or: return err
} else {
// Process(value)
}
為了更清晰的代碼,應(yīng)該總是使用包含錯誤值變量的 if 復(fù)合語句
上例除了 fmt.Printf
還可以使用 log 中對應(yīng)的方法(參見 13.3 節(jié) 和 15.2 節(jié)),如果程序中止也沒關(guān)系的話甚至可以使用 panic
(參見后面的章節(jié))。