golang 函数四 (错误处理)

前端之家收集整理的这篇文章主要介绍了golang 函数四 (错误处理)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

为了方便实现自定义错误类型,Go语言标准库中将error定义为接口类型。比如:

typeerrorinterface{
Error()string
}

按照Go语言编程习惯,error总是最后一个函数返回值,并且标准库提供了创建函数,可以方便的创建错误消息的error对象。比如:

funcdivTest(x,yint)(int,error){
ify==0{
return0,errors.New("divisionbyzero")//创建错误消息的error对象
}
returnx/y,nil
}
funcmain(){
v,err:=divTest(3,0)
iferr!=nil{
log.Fatalln(err.Error())
}
println(v)
}

日常开发中,我们需要根据需求自定义错误类型,可以存放更多的上下文信息,或者根据错误类型做出相应的错误处理。比如:

typeNegativeErrorstruct{
x,yint
}
func(NegativeError)Error()string{
return"negativevalueerror"
}

typeMolErrorstruct{
x,yint
}
func(MolError)Error()string{
return"devisionbyzero"
}

funcmolTest(x,MolError{x,y}
}
ifx<0||y<0{
return0,NegativeError{x,y}
}
returnx%y,nil
}

funcmain(){
v,err:=molTest(3,-1)
iferr!=nil{
switche:=err.(type){//获取错误类型
caseMolError:
println(e.x,e.y)
caseNegativeError:
println(e.x,e.y)
default:
println(e)
}
log.Fatalln(err.Error())
}
println(v)
}

与error相比,panic/recover 在应用上更类似于 try/catch 结构化。比如:

funcpanic()interface{}
funcrecover()interface{}

两者区别:panic 立即中断当前函数处理流程,执行延迟调用。recover在延迟调用中可以捕获并返回panic产生的错误对象,比如:

funcMyrecover(){
iferr:=recover();err!=nil{
log.Fatalln(err)
}
}

funcmain(){
println("start...")
deferMyrecover()
panic("dead")
println("end...")
}
输出:
start...
2017/02/0911:24:13dead
exitstatus1

如果有连续多次调用panic的场景,只有最后一次panic会被recover捕获处理,比如:

funcMyrecover(){
iferr:=recover();err!=nil{
log.Fatalln(err)
}
}

funcmain(){
deferMyrecover()
deferfunc(){
panic("abadproblem")
}()
panic("aproblem")
}
输出:
2017/02/0911:31:50abadproblem
exitstatus1

recover只有在延迟调用函数中才能得到正常工作,比如:

funcmain(){
deferMyrecover()
deferlog.Println(recover())
deferprintln(recover())
panic("aproblem")
}
输出:
(0x0,0x0)
2016/11/1207:07:54<nil>
2016/11/1207:07:54aproblem
exitstatus1

在日常开发过程中,经常需要进行调试,可以使用函数输出完整的调用栈信息,比如:

funcMyrecover(){
iferr:=recover();err!=nil{
fmt.Println(err)
debug.PrintStack()
//log.Fatalln(err)
}
}
funcmain(){
deferMyrecover()
panic("aproblem")
}
输出:
aproblem
goroutine1[running]:
runtime/debug.Stack(0xc42002c010,0xc42003fe20,0x1)
	/root/data/go/src/runtime/debug/stack.go:24+0x79
runtime/debug.PrintStack()
	/root/data/go/src/runtime/debug/stack.go:16+0x22
main.Myrecover()
	/root/data/gopath/test/panic.go:10+0x85
panic(0x48a5e0,0xc42000a320)
	/root/data/go/src/runtime/panic.go:458+0x243
main.main()
	/root/data/gopath/test/panic.go:16+0x8d

日常开发中,只有在系统发生了不可恢复性或无法正常工作的错误可以使用panic,比如端口号被占用、数据库未启动、文件系统错误等,否则不建议使用。

猜你在找的Go相关文章