Go 其八 错误机制
Go的错误机制
与其他主要编程语言的差异
- 没有异常机制
- error类型实现了error接口
- 可以通过errors.New来快速创建错误实例
//error类型实现了error接口
type error interface {
Error() string
}
//可以通过errors.New来快速创建错误实例
errors.New("n must be in the range [0,10]")
最佳实践
尽早失败,避免嵌套!
假如结构是没有错误就继续执行另一个方法func,但func仍可能会抛出异常,则会形成嵌套的结构。
这种时候可以改写成判断有错误就抛出,并Log.
emmmmmm,这个在其他的语言应该也是很常见的方式了。
panic
panic用于不可以恢复的错误
panic退出前会执行defer的内容 和前面的笔记一样,笔者是把defer当成别的语言的finnaly了,无论怎样都会执行(大多数情况下,好像看到Java有方法可以不执行,不是很了解,免抬杠注释.)
panic vs. os.Exit
os.Exit 退出时不会调用defer指定的函数的.(划重点) (啪啪打脸 ( ̄ε(# ̄)
os.Exit 退出时不输出当前调用栈信息
recover
defer func() {
if err := recover(); err != nil {
//恢复错误,recover会获取抛出的err.
}
}()
//Ps:感觉有些像Catch.
最常见的"错误恢复",这种方式其实是很危险的,代码如下:
defer func() {
if err := recover(); err != nil {
log.Error("recoverd panic", err)
}
}()
当心 recover 成为恶魔
形成僵尸服务进程,导致health check失效
"Let it Crash!"往往是我们恢复不确定性错误的最好方法。
就让它崩溃,然后利用守护进程重启.
Show the code:
关于Error
package error_test
import (
"fmt"
"errors"
"testing"
)
//区分错误类型,定义预置错误
var LessThanTwoError = errors.New("n should be not less than 2")
var LagerThanHundredError = errors.New("n should be not larger than 100")
func GetFibonacci(n int) ([] int, error) {
if n < 2 {
return nil, LessThanTwoError
}
if n > 100 {
return nil, LagerThanHundredError
}
fibList := []int{1,1}
for i:=2; i<n; i++{
fibList = append(fibList, fibList[i-2] + fibList[i-1])
}
return fibList, nil
}
func TestGetFibonacci(t *testing.T){
if v,err:=GetFibonacci(-10);err != nil{
if err == LessThanTwoError {
fmt.Println("Less than 2")
} else if err == LagerThanHundredError {
fmt.Println("Larger than 100")
}
}else{
t.Log(v)
}
}
Recover相关:
package panic_recover
import (
"errors"
"testing"
"fmt"
//"os"
)
func TestPanicVxExit(t *testing.T){
defer func() {
if err := recover(); err != nil {
fmt.Println("recovered from ", err)
}
}()
fmt.Println("Start")
panic(errors.New("Something wrong!")) //会输出调用栈信息,并执行defer
//os.Exit(-1) //不输出调用栈,不执行defer
}

浙公网安备 33010602011771号