16.10 糟糕的错误处理

最后更新于:2022-04-01 20:58:43

依附于[第13章](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/13.0.md)模式的描述和[第17.1小节](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/17.1.md)与[第17.2.4小节](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/17.2.md)的总结。 ## [](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/16.10.md#16101-不要使用布尔值)16.10.1 不要使用布尔值: 像下面代码一样,创建一个布尔型变量用于测试错误条件是多余的: ~~~ var good bool // 测试一个错误,`good`被赋为`true`或者`false` if !good { return errors.New("things aren’t good") } ~~~ 立即检测一个错误: ~~~ ... err1 := api.Func1() if err1 != nil { … } ~~~ ## [](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/16.10.md#16102-避免错误检测使代码变得混乱)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小节](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/13.5.md))。 在开始阅读[第17章](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/17.0.md)前,先回答下列2个问题: * 问题 16.1:总结你能记住的所有关于`,ok`模式的情况。 * 问题 16.2:总结你能记住的所有关于`defer`模式的情况。
';