Files
the-way-to-go_ZH_CN/eBook/16.10.md
Haigang Zhou 72bc74ab95 第十六章 (#846)
Co-authored-by: Joe Chen <jc@unknwon.io>
2022-05-17 16:36:50 +08:00

80 lines
2.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 arent 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)