menu arrow_back 湛蓝安全空间 |狂野湛蓝,暴躁每天 chevron_right All_wiki chevron_right the-way-to-go_ZH_CN chevron_right eBook chevron_right 16.10.md
  • home 首页
  • brightness_4 暗黑模式
  • cloud
    xLIYhHS7e34ez7Ma
    cloud
    湛蓝安全
    code
    Github
    16.10.md
    2.49 KB / 2024-07-16 23:14:29
        # 16.10 糟糕的错误处理
    
    译者注:该小结关于错误处理的观点,译者并不完全赞同,关于本小结的部分想法请参考 [关于 16.10.2 小节错误处理的一些见解](Discussion_about_16.10.md)。
    
    
    依附于[第 13 章](13.0.md)模式的描述和[第 17.1 小节](17.1.md)与[第 17.2.4 小节](17.2.md)的总结。
    
    ## 16.10.1 不要使用布尔值:
    
    像下面代码一样,创建一个布尔型变量用于测试错误条件是多余的:
    
    ```go
    var good bool
        // 测试一个错误,`good` 被赋为 `true` 或者 `false`
        if !good {
            return errors.New("things aren’t good")
        }
    ```
    
    立即检测一个错误:
    
    ```go
    ... err1 := api.Func1()
    if err1 != nil { … }
    ```
    
    ## 16.10.2 避免错误检测使代码变得混乱:
    
    避免写出这样的代码:
    
    ```go
    ... err1 := api.Func1()
    if err1 != nil {
        fmt.Println("err: " + err.Error())
        return
    }
    err2 := api.Func2()
    if err2 != nil {
    ...
        return
    }    
    ```
    
    首先,包括在一个初始化的 `if` 语句中对函数的调用。但即使代码中到处都是以 `if` 语句的形式通知错误(通过打印错误信息)。通过这种方式,很难分辨什么是正常的程序逻辑,什么是错误检测或错误通知。还需注意的是,大部分代码都是致力于错误的检测。通常解决此问题的好办法是尽可能以闭包的形式封装你的错误检测,例如下面的代码:
    
    ```go
    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 小节](13.5.md))。
    
    **在开始阅读[第 17 章](17.0.md)前,先回答下列 2 个问题:**
    
    - 问题 16.1:总结你能记住的所有关于 `, ok` 模式的情况。
    
    - 问题 16.2:总结你能记住的所有关于 `defer` 模式的情况。
    
    
    ## 链接
    
    - [目录](directory.md)
    - 上一节:[闭包和协程的使用](16.9.md)
    - 下一章:[Go 语言模式](17.0.md)
    
    
    links
    file_download