Go的错误机制
- 没有异常机制
- error类型实现了error接口
- 可以通过errors.New来快速创建错误实例,
errors.New("n must be in the range [0, 10]")
如何使用错误机制?
func GetFibonacci(n int) ([]int, error) {
//错误处理
if n < 2 || n > 100 {
return nil, errors.New("n should be in [2, 100]")
}
fibList := []int{1, 1}
for i := 2; i < n; i++ {
//加入到集合当中
fibList = append(fibList, fibList[i-1]+fibList[i-2])
}
return fibList, nil
}
func TestGetFibonacci(t *testing.T) {
//判断是否出错
if v, err := GetFibonacci(-10); err != nil {
t.Error(err)
} else {
t.Log(v)
}
}
优雅使用错误机制
//预先定义错误,方便后续对错误进行判断
var LessThanTwoError = errors.New("n should be not less than 2")
var LargerThanHundredError = 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, LargerThanHundredError
}
fibList := []int{1, 1}
for i := 2; i < n; i++ {
//加入到集合当中
fibList = append(fibList, fibList[i-1]+fibList[i-2])
}
return fibList, nil
}
func TestGetFibonacci(t *testing.T) {
//判断是否出错
if v, err := GetFibonacci(-10); err != nil {
if err == LessThanTwoError {
fmt.Println("n < 2")
} else if err == LargerThanHundredError {
fmt.Println("n > 100")
} else {
fmt.Println("Unkown Error")
}
} else {
t.Log(v)
}
}
panic与os.Exit
panic
- panic用于不可恢复的错误
- panic退出前会执行defer指定的内容
func TestPainicVsExit(t *testing.T) {
defer func() {
fmt.Println("Finally")
}()
fmt.Println("Start")
panic(errors.New("Something wrong!"))
//os.Exit(-1)
fmt.Println("End")
}
os.Exit
- os.Exit退出时不会调用defer指定的函数
- os.Exit退出时不输出当前调用栈信息
func TestPainicVsExit(t *testing.T) {
defer func() {
fmt.Println("Finally")
}()
fmt.Println("Start")
//panic(errors.New("Something wrong!"))
os.Exit(-1)
fmt.Println("End")
}
recover(不推荐使用)
- 形成僵尸服务进程,导致health check失效
- “Let it Crash!”往往是我们恢复不确定性错误的最好方法
func TestPainicVsExit(t *testing.T) {
//错误恢复
defer func() {
if err := recover(); err != nil {
fmt.Println("recovered from", err)
}
}()
fmt.Println("Start")
panic(errors.New("Something wrong!"))
//os.Exit(-1)
fmt.Println("End")
}
本文章参考来自Go语言从入门到实战