go的错误处理不同与其他语言,他没有try catch 或者except。反而每个函数都有一个预期的错误返回,和这个函数的调用者将会检查函数错误返回值并给出适当的动作。当Go函数回一个错误的时候,这里有5种通用策略去处理它。
1.错误传递
所以一个错误在子程序将会被视为调用程序的失败。这个简单的例子是由在下面的2个函数来表示。在GetLink()函数中的所有错误将会返回到主函数中,并且这是一个非常常见的策略在Go的错误操作。
package main
import (
"fmt"
"net/http"
)
func getLink() (*http.Response, error) {
content, err := http.Get("www.google.com")
if nil != err {
return nil, err
}
return content, err
}
func main() {
resp, err := getLink()
if nil != err {
return
}
fmt.Println(resp)
}
2.在处于异常时再进行重试
因为这个错误是不可预知或者是短暂的,进行再次操作是中明智的选择,可能是延迟和假定一个极限的尝试次数或者是在完全放弃之前进行的尝试。
package main
import (
"fmt"
"net/http"
"time"
)
func waitForResponse() error {
const timeout = 1 * time.Minute
deadline := time.Now().Add(timeout)
url := "www.google.com"
for tries := 0; time.Now().Before(deadline); tries++ {
_, err := http.Get(url)
if err == nil {
return nil
}
fmt.Println("Server not responding. Retrying again")
}
return fmt.Errorf("Server faild to respond after the time")
}
func main() {
err := waitForResponse()
if nil != err {
return
}
}
3.更优雅的退出程序
如果这个进程在遇到这个错误之后是致命的,然后进程可以很好的打印这个错误并且完美的退出在项目中,但是这个策略会只使用于主进程。
任何错误在子进程或者子函数中,都应该被传递,和这个子进程应当不满足这个策略。
当然这个错误日志可以使用log包来结束会更优雅。这个log包提供更多关于错误的附加信息对于长期运行的程序来说是非常有用的。
所以log包将会提供关于错误更确切的时间和日期。
4.记录日志继续执行
当对于这个错误仅仅只需要记录然后程序继续执行,亦或者是减少了功能这一种情况。
5.忽略错误
这将是最糟糕的策略,他将会忽略错误并且继续执行。
如果使用这个策略,则忽略这个错误但不要忽略文档。
记录了一些例子