Golang官方推荐的错误处理方式,是建议把err放在每个函数的返回值的最后,也就是每个函数返回至少两个值,一个是正常的结果一个是err。我们在日常的编码中也需要遵循这样的规则来定义func。
这谁能接受?如果这样的话那得话多少时间来处理异常。还好后来出现了recover,可以用它来捕获异常。
recover
如果在defer函数中调用了内置函数recover,并且定义该defer语句的函数发生了panic异常,recover会使程序从panic中恢复,并返回panic value。导致panic异常的函数不会继续运行,但能正常返回。在未发生panic时调用recover,recover会返回nil。让我们以语言解析器为例,说明recover的使用场景。考虑到语言解析器的复杂性,即使某个语言解析器目前工作正常,也无法肯定它没有漏洞。因此,当某个异常出现时,我们不会选择让解析器崩溃,而是会将panic异常当作普通的解析错误,并附加额外信息提醒用户报告此错误。
示例:
package main import "log" func main() { defer func(){ if r := recover();r!=nil{ log.Printf("Runtime error caught: %v",r) } }() a := 1 if a == 1{ panic("nice") } }
如此看来,只要我们在定义每个函数的时候加上上述的defer 语句就可以了,但是这样代码显得冗余,我们再封装一下:
package main import ( "errors" "log" ) func main() { test() } func test() { defer CoverErrorMessage() panic(111) } func CoverErrorMessage() { if message := recover(); message != nil { var err error switch x := message.(type) { case string: err = errors.New(x) case error: err = x default: err = errors.New("Unknow panic") } log.Print("Recovered panic error : ",err) } }