第九章:错误处理

Go语言设计者认为类似try-catch-finally的传统异常处理机制很容易造成开发者对异常机制的滥用,Go语言中推荐多值返回来返回错误,这种检查错误的方式给程序员提供了很大的控制权。
错误定义:

error类型其实是一个接口。

type error interface{
	Error()   string
}

error接口包含Error()方法,返回一个字符串。这意味着所有包含Error() string 格式的方法都可以实现错误接口

创建错误:使用errors包的New函数创建自定义错误
func main(){
	err := errors.New("this is a err!")
	var err2 error
	fmt.Println(err.Error())
	fmt.Println(err)  //同上
	fmt.Println(err2)
}
//结果为:
this is a err!
this is a err!
<nil>
自定义错误格式:fmt.Errorf() 本质上还是调用errors包的New方法创建错误,并使用Springf方法对错误格式化。
func main(){
	if _,_,line,ok := runtime.Caller(0);ok{
		err := fmt.Errorf("***Line %d error***",line)
		fmt.Println(err.Error())
	}  
}

//fmt.Errorf()源码
func Errorf(format string,a ...interface{}) error {
	return errors.New(Sprintf(format,a...))
}
触发宕机

一般而言,只有当程序发生不可逆的错误时,才使用panic方法触发宕机。
func panic (v interface{})   可以看到传入任意类型的值作为宕机内容都可以

使用panic方法后,程序的执行将直接中断,但是会调用延迟执行语句defer,可与recover()配合捕获宕机

func main(){
	panic("serious bug")
	fmt.Println("Invalid Code")  //程序退出,无法执行该行代码
}
适用场景:

1、程序处于失控状态且无法恢复,继续执行将影响其他正常程序,引发操作系统异常甚至是死机
2、发生不可预知的错误

宕机恢复

通过内置函数recover来捕获宕机,类似try-catch机制

在使用panic方法触发宕机后,在推出当前函数之前,会调用延迟执行语句defer。
故我们可以通过defer语句+匿名函数+recover方法完成对宕机的捕获

func protect(){
	defer func(){
		if err := recover();err !=nil{    //recover()获取panic()传入的参数
			fmt.Println(err)
		}
	}()
	panic("serious bug!")
}

func main(){
	protect()
	fmt.Println("valid code")
}
//结果为:
serious bug!
valid code
recover应用:安全模式

专门封装一个函数,以一种安全模式来运行所有传入的方法

func protect(f func()){
	defer func(){
		if err := recover();err!= nil{
			fmt.Println(err)
		}
	}()
	f()
}

func main(){
	protect(func () {
		fmt.Println("This is function 1")
		panic("Serious bug from function1")
	})
	protect(func () {
		fmt.Println("This is function 2")
		panic("Serious bug from function2")
	})
	fmt.Println("valid code")
}

//结果为:
This is function 1
Serious bug from function1
This is function 2
Serious bug from function2
valid code

panic()和recover()虽然可以模拟其他语言的异常机制,但是并不建议在Go语言编程中使用类似的方法,推荐使用多值返回错误。

拓展:error 接口的应用

上面说到实现Error()string的接口都可以实现error接口

type ErrNegSqrt float64

func (e ErrNegSqrt) Error() string{
	return fmt.Printf("cannot Sqrt negative number: %v",float64(e))
}

func sqrt(x float64) (float64,error){
	if x < 0.0{
		return 0,ErrNegSqrt(x)
	}else{
		return math.Sqrt(x),nil
	}
}

func main(){
	res,err := sqrt(-2)
	if err != nil{
		fmt.Println(err)
	}else{
		fmt.Println(res)
	}
}
//结果为:
cannot Sqrt negative number: -2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值