分享
  1. 首页
  2. 文章

GoLang之错误处理

chenny7 · · 8490 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

错误处理

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(){
 ...
}()


注意,defer语句是在return之后执行的,例如:

func test() (result int) {
 defer func() {
 result = 12
 }()
 return 10
}
func main() {
 fmt.Println(test()) // 12
}

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之后返回。


func foo() { panic(errors.New("i'm a bug")) return } func test() (result int) { defer func() { if r := recover(); r != nil { err := r.(error) fmt.Println("Cache Exception:", err) } }() foo() return 10 } func main() { fmt.Println(test()) // 0 }

注意,在一个函数中panic被调用后,其defer语句仍会执行,

func foo()(n int) {
 defer func() {
 if r := recover(); r != nil {
 n++ // take effective
 }
 }()
 n++ // take effective
 panic(errors.New("i'm a bug"))
 n++ // take no effective
 return n
}

有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:chenny7

查看原文:GoLang之错误处理

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
8490 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏