为了方便实现自定义错误类型,Go语言标准库中将error定义为接口类型。比如:
type error interface{
Error() string
}
按照Go语言编程习惯,error总是最后一个函数返回值,并且标准库提供了创建函数,可以方便的创建错误消息的error对象。比如:
func divTest(x ,y int)(int, error){
if y == 0{
return 0, errors.New("division by zero") //创建错误消息的error对象
}
return x/y,nil
}
func main(){
v, err := divTest(3,0)
if err != nil{
log.Fatalln(err.Error())
}
println(v)
}
日常开发中,我们需要根据需求自定义错误类型,可以存放更多的上下文信息,或者根据错误类型做出相应的错误处理。比如:
type NegativeError struct{
x, y int
}
func (NegativeError)Error()string{
return "negative value error"
}
type MolError struct {
x, y int
}
func (MolError)Error()string{
return "devision by zero"
}
func molTest(x ,y int)(int, error){
if y == 0{
return 0, MolError{x,y}
}
if x < 0 || y < 0{
return 0, NegativeError{x,y}
}
return x%y,nil
}
func main(){
v, err := molTest(3,-1)
if err != nil{
switch e := err.(type){ //获取错误类型
case MolError:
println(e.x,e.y)
case NegativeError:
println(e.x,e.y)
default:
println(e)
}
log.Fatalln(err.Error())
}
println(v)
}
与error相比,panic/recover 在应用上更类似于 try/catch 结构化。比如:
func panic() interface{}
func recover() interface{}
两者区别:panic 立即中断当前函数处理流程,执行延迟调用。recover在延迟调用中可以捕获并返回panic产生的错误对象,比如:
func Myrecover(){
if err := recover(); err != nil{
log.Fatalln(err)
}
}
func main(){
println("start...")
defer Myrecover()
panic("dead")
println("end...")
}
输出:
start...
2017/02/09 11:24:13 dead
exit status 1
如果有连续多次调用panic的场景,只有最后一次panic会被recover捕获处理,比如:
func Myrecover(){
if err := recover(); err != nil{
log.Fatalln(err)
}
}
func main(){
defer Myrecover()
defer func(){
panic("a bad problem")
}()
panic("a problem")
}
输出:
2017/02/09 11:31:50 a bad problem
exit status 1
recover只有在延迟调用函数中才能得到正常工作,比如:
func main() {
defer Myrecover()
defer log.Println(recover())
defer println(recover())
panic("a problem")
}
输出:
(0x0,0x0)
2016/11/12 07:07:54 <nil>
2016/11/12 07:07:54 a problem
exit status 1
在日常开发过程中,经常需要进行调试,可以使用函数输出完整的调用栈信息,比如:
func Myrecover(){
if err := recover(); err != nil{
fmt.Println(err)
debug.PrintStack()
//log.Fatalln(err)
}
}
func main(){
defer Myrecover()
panic("a problem")
}
输出:
a problem
goroutine 1 [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,比如端口号被占用、数据库未启动、文件系统错误等,否则不建议使用。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。