16.10 糟糕的錯誤處理

依附於第13章模式的描述和第17.1小節第17.2.4小節的總結。

16.10.1 不要使用布爾值:

像下面代碼一樣,創建一個布爾型變量用於測試錯誤條件是多餘的:

var good bool
    // 測試一個錯誤,`good`被賦爲`true`或者`false`
    if !good {
        return errors.New("things aren’t good")
    }

立即檢測一個錯誤:

... err1 := api.Func1()
if err1 != nil { … }

16.10.2 避免錯誤檢測使代碼變得混亂:

避免寫出這樣的代碼:

... err1 := api.Func1()
if err1 != nil {
    fmt.Println("err: " + err.Error())
    return
}
err2 := api.Func2()
if err2 != nil {
...
    return
}

首先,包括在一個初始化的if語句中對函數的調用。但即使代碼中到處都是以if語句的形式通知錯誤(通過打印錯誤信息)。通過這種方式,很難分辨什麼是正常的程序邏輯,什麼是錯誤檢測或錯誤通知。還需注意的是,大部分代碼都是致力於錯誤的檢測。通常解決此問題的好辦法是儘可能以閉包的形式封裝你的錯誤檢測,例如下面的代碼:

func httpRequestHandler(w http.ResponseWriter, req *http.Request) {
    err := func () error {
        if req.Method != "GET" {
            return errors.New("expected GET")
        }
        if input := parseInput(req); input != "command" {
            return errors.New("malformed command")
        }
        // 可以在此進行其他的錯誤檢測
    } ()

        if err != nil {
            w.WriteHeader(400)
            io.WriteString(w, err)
            return
        }
        doSomething() ...

這種方法可以很容易分辨出錯誤檢測、錯誤通知和正常的程序邏輯(更詳細的方式參考第13.5小節)。

在開始閱讀第17章前,先回答下列2個問題:

  • 問題 16.1:總結你能記住的所有關於,ok模式的情況。

  • 問題 16.2:總結你能記住的所有關於defer模式的情況。

鏈接

results matching ""

    No results matching ""