error
可预知的错误
有些预料中的错误 , 会作为函数的第二个返回值 , 可以使用 fmt.Errorf('%v',err)
封装错误, 使用 Unwrap
来获取上一层的错误
由于错误信息经常是以链式组合在一起的,所以错误信息中应避免大写和换行符。
不可预知的 , 偶然的
一个明智的选择是重新尝试失败的操作。在重试时,我们需要限制重试的时间间隔或重试的次数,防止无限制的重试。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
func WaitForServer(url string) error {
const timeout = 1 * time.Minute
deadline := time.Now().Add(timeout)
for tries := 0; time.Now().Before(deadline); tries++ {
_, err := http.Head(url)
if err == nil {
return nil // success
}
log.Printf("server not responding (%s);retrying…", err)
time.Sleep(time.Second << uint(tries)) // exponential back-off
}
return fmt.Errorf("server %s failed to respond after %s", url, timeout)
}
|
当你想忽略某个错误时 , 应该清晰的写下意图
Go中大部分函数的代码结构几乎相同,首先是一系列的初始检查,防止错误发生,之后是函数的实际逻辑。
在Go中,错误处理有一套独特的编码风格。检查某个子函数是否失败后,我们通常将处理失败的逻辑代码放在处理成功的代码之前。如果某个错误会导致函数返回,那么成功时的逻辑代码不应放在else语句块中,而应直接放在函数体中。
文件结尾错误 EOF
io包保证任何由文件结束引起的读取失败都返回同一个错误——io.EOF
源码
1
2
3
|
type error interface{
Error() string
}
|