Go 語(yǔ)言中的錯(cuò)誤和異常處理
在 Go 語(yǔ)言中沒(méi)有與 Java 或者 .NET 類(lèi)似的異常處理機(jī)制。Go 語(yǔ)言的開(kāi)發(fā)者認(rèn)為類(lèi)似的異常處理已經(jīng)被過(guò)多的使用了,這樣的異常機(jī)制過(guò)度依賴上層代碼對(duì)異常的處理,如果上層代碼對(duì)異常的處理不到位會(huì)使程序出一些不易排查的BUG。所以為了讓開(kāi)發(fā)者能夠重視并正確的處理每一個(gè)可能會(huì)出現(xiàn)異常的函數(shù),Go語(yǔ)言采用返回值的形式來(lái)返回錯(cuò)誤。這一機(jī)制,既可以讓開(kāi)發(fā)者真正理解錯(cuò)誤處理的含義,也可以大大降低程序的復(fù)雜度。
1.error 接口
error 是系統(tǒng)自帶的一個(gè)接口類(lèi)型的自定義類(lèi)型。
代碼如下:
type error interface {
Error() string
}
2. errors 包
Tips:包的概念會(huì)在后文的Go語(yǔ)言中的包管理中詳細(xì)介紹
errors 包中包含了一個(gè)實(shí)現(xiàn)了 error 這個(gè)接口的結(jié)構(gòu)體類(lèi)型 errorString。我們可以直接使用包中的方法來(lái)自定義一些錯(cuò)誤,從而返回我們希望被上層代碼處理的錯(cuò)誤信息。
代碼示例:
package main
import (
"errors"
"fmt"
)
func main() {
t, err := divide(2, 0)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(t)
}
}
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("除數(shù)不能為0")
}
return a / b, nil
}
- 第 19 行:使用 errors.New 自定義一個(gè)除數(shù)不能為0的錯(cuò)誤;
- 第 10~12 行:若除數(shù)為零,則輸出這個(gè)錯(cuò)誤。
執(zhí)行結(jié)果:

3. 異常處理
如果你調(diào)用的方法的開(kāi)發(fā)者不夠仔細(xì),并沒(méi)有將所有的異常都考慮到并作為錯(cuò)誤返回,那你的程序可能就會(huì)被其影響而崩潰。對(duì)這種情況,GO 語(yǔ)言提供了一個(gè)叫recover()的函數(shù),用于處理這種問(wèn)題。一般常用于服務(wù)啟動(dòng)的入口函數(shù),因?yàn)榫W(wǎng)絡(luò)等外部因素,極有可能會(huì)導(dǎo)致程序異常,這些異常就需要這個(gè)函數(shù)來(lái)捕獲。
代碼示例:
package main
import (
"fmt"
)
func main() {
defer func() {
err := recover()
if err != nil {
fmt.Println("程序運(yùn)行中出現(xiàn)異常:", err)
}
}()
t := divide(2, 0)
fmt.Println(t)
}
func divide(a, b int) int {
return a / b
}
- 第 17 行:在沒(méi)有判斷除數(shù)的情況下直接做除法,若除數(shù)為零,程序直接崩潰。
- 第 8~11 行:在 main 函數(shù)結(jié)束時(shí),獲取執(zhí)行過(guò)程中的錯(cuò)誤,若沒(méi)有錯(cuò)誤者err為nil。
執(zhí)行結(jié)果:

4. 小結(jié)
本位介紹了 Go 語(yǔ)言中如何使用 errors 包來(lái)自定義錯(cuò)誤,如何去使用函數(shù)中返回出來(lái)的 error 類(lèi)型變量,來(lái)處理自定義錯(cuò)誤以及在無(wú)法避免的異常出現(xiàn)的時(shí)候如何使用recover()來(lái)保障程序不崩潰。
Codey ·
2025 imooc.com All Rights Reserved |