GO语言Error处理

Posted aresxin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GO语言Error处理相关的知识,希望对你有一定的参考价值。

Go语言没有提供像Java、C#、Python语言中的try...catch异常处理方式,而是通过函数返回值逐层往上抛。好处就是避免漏掉本应处理的错误。坏处是代码啰嗦。

错误与异常区别

错误指的是可能出现问题的地方出了问题,比如打开文件失败。
异常是不应该出现问题的地方出了问题,比如空指针。
Go中的错误是一种类型,错误用内置的error类型(接口)来表示。错误可以存储在变量中,从函数中返回。

type error interface 
    Error() string

创建自定义错误

创建自定义错误可用errors包下的New()函数以及fmt包下的Errorf()函数。

//创建一个error的数据
    err1 := errors.New("自己创建...")
    fmt.Println(err1)
    fmt.Printf("%T\n", err1) //*errors.fundamental
    //创建一个error方法
    err2 := fmt.Errorf("错误码:%d", 10000)
    fmt.Println(err2)   //错误码:10000
    fmt.Printf("%T\n", err2)    //*errors.errorString

自定义错误示例

//求矩形面积
type areaError struct 
    msg    string  //错误描述
    length float64 //矩形长度
    wigth  float64 //矩形宽度


func (e *areaError) Error() string 
    return e.msg

func (e *areaError) lengthNegative() bool 
    return e.length < 0 //如果比0小,返回false

func (e *areaError) wigthNegative() bool 
    return e.wigth < 0 //如果比0小,返回false

func revArea(length, wigth float64) (float64, error) 
    msg := ""
    if length < 0 
        msg = "长度小于0"
    
    if wigth < 0 
        if msg == "" 
            msg = "宽度小于0"
         else 
            msg += ",宽度小于0"
        
    
    if msg != "" 
        return 0, &areaErrormsg, length, wigth
    
    return length * wigth, nil

func main() 
    length, wigth := -4.3, -6.7
    area, err := revArea(length, wigth)
    if err != nil 
        fmt.Println(err)
        //断言判断具体error
        if err, ok := err.(*areaError); ok 
            if err.lengthNegative() 
                fmt.Printf("error:长度,%.2f小于0\n", err.length)
            
            if err.wigthNegative() 
                fmt.Printf("error:宽度,%.2f小于0\n", err.wigth)
            
        
        return
    
    fmt.Println("矩形面积是:", area)

输入:
长度小于0,宽度小于0
error:长度,-4.30小于0
error:宽度,-6.70小于0

panic/recover

GO可以使用panic/recover模式来处理错误。 panic可以在任何地方引发,但recover只有在defer调用的函数中有效。
等到包含defer语句的函数执行完毕时,延迟函数(defer后的函数)才会被执行,而不管包含defer语句的函数是通过return的正常结束,还是由于panic导致的异常结束,你可以在一个函数中执行多条 defer语句,它们的执 行顺序与声明顺序相反。

panic:

  1. 内建函数
  2. 假如函数F中书写了panic语句,会终止其后要执行的代码,在panic所在函数F内如果存在要执行的defer函数列表,按照defer的逆序执行
  3. 返回函数F的调用者G,在G中,调用函数F语句之后的代码不会执行,假如函数G中存在要执行的defer函数列表,按照defert的逆序执行,这里的 defer有点类似 try-catch-finally中的finally
  4. 直到 goroutine整个退出,并报告错误

recover

  1. 内建函数
  2. 用来控制一个goroutine的panicking行为,捕获panic,从而影响应用的行为
  3. 一般的调用建议:在defer函数中,通过recever来终止一个goroutine的 panicking过程,从而恢复正常代码的执行;可以获取通过panic传递的 error
    简单来讲go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理.

实例

func a()  
    fmt.Println("func a")

func b()  
    panic("func b")

func c()  
    fmt.Println("func c")

func main()  
    a()
    b()
    c()

执行到func b的时候会抛出异常,程序崩溃,可以使用recover将程序恢复

func a()  
    fmt.Println("func a")

func b()  
    defer func() 
        err := recover()
        if err != nil
            fmt.Println("recover fun b")
        
    ()
    panic("func b")

func c()  
    fmt.Println("func c")

func main()  
    a() //func a
    b() //recover fun b
    c() //func c

  • recover()必须搭配defer使用。
  • defer一定要在可能引发panic的语句之前定义。

以上是关于GO语言Error处理的主要内容,如果未能解决你的问题,请参考以下文章

2.11 Go之error接口

GO语言学习(十九)Go 错误处理

GO语言基础之error

GO_10:GO语言基础之error

Go 语言:如何利用好 TDD 学习指针并了解 Golang 中的 error 处理

Go语言的异常处理之errors,panic, recover