GoLang之错误处理

Posted 千里之外

tags:

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

 

 

错误处理

 

error

Go语言引入了一个错误处理的标准模式,即error接口,该接口定义如下:

type error interface {
    Error() string
}

 

对于大多数函数,如果要返回错误,可以将error作为多返回值的最后一个:

func foo(param int)(ret int, err error)
{
  ...  
}

 

调用时的代码:

n, err := foo(0)
if err != nil {
    //  错误处理
} else {
    // 使用返回值n
}

 

我们还可以自定义错误类型,一个例子:

package main
 
import "fmt"
import "errors"
 
//自定义的出错结构
type myError struct {
    arg  int
    errMsg string
}
//实现Error接口
func (e *myError) Error() string {
    return fmt.Sprintf("%d - %s", e.arg, e.errMsg)
}
 
//两种出错
func error_test(arg int) (int, error) {
    if arg < 0  {
         return -1, errors.New("Bad Arguments - negtive!")
     }else if arg >256 {
        return -1, &myError{arg, "Bad Arguments - too large!"}
    }
    return arg*arg, nil
}
 
//相关的测试
func main() {
    for _, i := range []int{-1, 4, 1000} {
        if r, e := error_test(i); e != nil {
            fmt.Println("failed:", e)
        } else {
            fmt.Println("success:", r)
        }
    }
}

 

 

 

defer 

你可以在Go函数中添加多个defer语句,当函数执行到最后时,这些defer语句会按照逆序执行(即最后一个defer语句将最先执行),最后该函数返回。

特别是当你在进行一些打开资源的操作时,遇到错误需要提前返回,在返回前你需要关闭相应的资源,不然很容易造成资源泄露等问题。如下代码所示,我们一般写打开一个资源是这样操作的:

func CopyFile(dst, src string) (w int64, err error) {
    srcFile, err := os.Open(src)
    if err != nil {
        return 
    }

    defer srcFile.Close()

    dstFile, err := os.Create(dst)
    if err != nil {
        return 
    }

    defer dstFile.Close()

    return io.Copy(dstFile, srcFile)
}

 

如果defer后面一条语句干不完清理工作,也可以使用一个匿名函数:

defer func(){
    ...
}()

 

 

panic() recover()

panic()函数用于抛出异常,recover()函数用于捕获异常,这两个函数的原型如下:

func panic(interface{})
func recover() interface{}

 

当在一个函数中调用panic()时,正常的函数执行流程将立即终止,但函数中之前使用defer关键字延迟执行的语句将正常展开执行,之后该函数将返回到调用函数,并导致逐层向上执行panic()流程,直至所属的goroutine中所有正在执行的函数被终止。错误信息将被报告,包括在调用panic()函数时传入的参数,这个过程称为错误流程处理。

panic()接受一个interface{}参数,可支持任意类型,例如:

panic(404)
panic("network broken")
panic(Error("file not exists"))

 

在defer语句中,可以使用recover()终止错误处理流程,这样可以避免异常向上传递,但要注意recover()之后,程序不会再回到panic()那里,函数仍在defer之后返回。

defer func() {
    if r := recover(); r != nil {
        // catch exception 
    }
}()

 

以上是关于GoLang之错误处理的主要内容,如果未能解决你的问题,请参考以下文章

干货大放送~golang错误处理之error

golang goroutine例子[golang并发代码片段]

golang代码片段(摘抄)

代码片段 - Golang 实现集合操作

Golang错误处理

golang如何优雅的处理错误