diff --git a/zh/12.2.md b/zh/12.2.md index 67ad1965..1c43f319 100644 --- a/zh/12.2.md +++ b/zh/12.2.md @@ -31,6 +31,8 @@ 通知用户在访问页面的时候我们可以有两种错误:404.html和error.html,下面分别显示了错误页面的源码: +```html +
@@ -51,8 +53,11 @@ +``` 另一个源码: +```html + @@ -74,8 +79,11 @@ +``` 404的错误处理逻辑,如果是系统的错误也是类似的操作,同时我们看到在: +```Go + func (p *MyMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/" { sayhelloName(w, r) @@ -99,10 +107,12 @@ t.Execute(w, ErrorInfo) //执行模板的merger操作 } +``` ## 如何处理异常 我们知道在很多其他语言中有try...catch关键词,用来捕获异常情况,但是其实很多错误都是可以预期发生的,而不需要异常处理,应该当做错误来处理,这也是为什么Go语言采用了函数返回错误的设计,这些函数不会panic,例如如果一个文件找不到,os.Open返回一个错误,它不会panic;如果你向一个中断的网络连接写数据,net.Conn系列类型的Write函数返回一个错误,它们不会panic。这些状态在这样的程序里都是可以预期的。你知道这些操作可能会失败,因为设计者已经用返回错误清楚地表明了这一点。这就是上面所讲的可以预期发生的错误。 但是还有一种情况,有一些操作几乎不可能失败,而且在一些特定的情况下也没有办法返回错误,也无法继续执行,这样情况就应该panic。举个例子:如果一个程序计算x[j],但是j越界了,这部分代码就会导致panic,像这样的一个不可预期严重错误就会引起panic,在默认情况下它会杀掉进程,它允许一个正在运行这部分代码的goroutine从发生错误的panic中恢复运行,发生panic之后,这部分代码后面的函数和代码都不会继续执行,这是Go特意这样设计的,因为要区别于错误和异常,panic其实就是异常处理。如下代码,我们期望通过uid来获取User中的username信息,但是如果uid越界了就会抛出异常,这个时候如果我们没有recover机制,进程就会被杀死,从而导致程序不可服务。因此为了程序的健壮性,在一些地方需要建立recover机制。 +```Go func GetUser(uid int) (username string) { defer func() { @@ -114,7 +124,7 @@ username = User[uid] return } - +``` 上面介绍了错误和异常的区别,那么我们在开发程序的时候如何来设计呢?规则很简单:如果你定义的函数有可能失败,它就应该返回一个错误。当我调用其他package的函数时,如果这个函数实现的很好,我不需要担心它会panic,除非有真正的异常情况发生,即使那样也不应该是我去处理它。而panic和recover是针对自己开发package里面实现的逻辑,针对一些特殊情况来设计。 ## 小结