Go语言错误处理

幸运草
幸运草
幸运草
1033
文章
3
评论
2020年4月16日20:53:24
评论
202

学习错误处理是任何一门语言都必须有的一个重要内容,Go语言漂亮的错误处理也是它的亮点之一。

一、error接口

标准库将error定义为接口类型,以便于自己定义错误类型。

type error interface{
Error() string
}

通常,error总是最后一个返回参数。标准库提供了相关创建函数,可方便的创建包含简单错误文本的error对象。

var errDivByZero = errors.New("division by zero")

func div(x,y int)(int,error){
if y == 0{
return 0,errDivByZero
   }

return x/y,nil
}

func main(){
z,err := div(5,0)
if err == errDivByZero{
      log.Fataln(err)
   }

   fmt.Println(z)
}

错误变量通常以err作为前缀,且字符串内容全部小写,没有结束标点,以便于嵌入到其他格式化字符串中输出。

全局错误变量并非没有问题,因为他们可被用户重新赋值,这就可能导致结果不匹配。

与errors.New类似的还有fmt.Errorf,它返回一个格式化内容的错误对象。

Go语言总接口的灵活性,你根本不需要从error接口继承或者像Java一样需要使用implemments来明确指定类型和接口之间的关系。

type pathError struct{
Op string
   Path string
   Err error
}

关键在于下面的代码实现了Error()方法:

func (e *pathError) Error() string{
return e.Op + " " + e.Path + e.Err.Error()
}

大量的函数和方法返回error,使得调用的代码变得很难看,不够简洁,可以用一下办法解决。

  • 使用专门的检查工具检查函数处理错误逻辑(比如记录日志),简化检查代码。
  • 在不影响逻辑的情况下,使用defer延后处理错误状态(err退化赋值)。
  • 在不中断逻辑的情况下,将错误作为内部状态报错,等最终”提交”时再处理。

二、panic与recover

panic会中断当前的函数流程,执行延迟调用。而在延迟函数中,recover可以捕捉并返回panic提交的错误对象。

func main(){
defer func(){
if err:=recover();err!=nil{
         log.Fatalln(err)
      }
   }()

panic("i am panic")
println("exit")
}

因为panic参数是空接口类型,因此可使用任何对象作为错误状态。而recover返回结果同样要做转型才能获得具体信息。

无论是否执行recover,所有的延迟函数调用都会执行。当中断性错误会沿调用堆栈向外传递,要么被外层捕获,要么导致进程崩溃。

连续调用panic,仅最后一个会被recover捕获。

在延迟函数中panic,不会影响后续延迟调用执行。而recover之后panic,可被再次捕获。另外,recover必须在延迟函数中执行才能正常工作。

    func catch(){
      log.Println("catch:".recover())
   }

func main(){
defer catch()
defer log.Println(recover())
defer recover()

panic("i am panic")
   }


输出:
<nil>
      catch:i am panic

特别声明:以上文章内容仅代表作者本人观点,不代表变化吧观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

转载请注明:{{title}}-变化吧
  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 赞助本站
  • 支付宝扫一扫
  • weinxin
幸运草
Go语言接口规则 前端框架

Go语言接口规则

Go语言接口规则 接口是一个或多个方法签名的集合。任何类型的方法集中只要拥有该接口对应的全部方法签名。就表示它 "实现" 了该接口,无须在该类型上显式声明实现了哪个接口。对应方法,是指有相同名称、参数...
Go语言中处理 HTTP 服务器 前端框架

Go语言中处理 HTTP 服务器

1 概述 包 net/http 提供了HTTP服务器端和客户端的实现。本文说明关于服务器端的部分。 快速开始: package main import (   "log"   "net/http" )...