go_错误处理

错误表示程序中出现异常情况
假设我们正在视图打开一个文件,但时这个文件不存在。这是一种异常情况,它表示错误

Go中的错误使用内置error类型

错误示例

尝试打开一个不存在的文件:

package main
 
import (  
    "fmt"
    "os"
)
 
func main() {  
    f, err := os.Open("/test.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(f.Name(), "opened successfully")
}

如果文件已成功打开,则 Open 函数将返回文件处理程序,并且错误将为 nil。如果打开文件时出错,将返回一个非零错误。

Go 中处理错误的惯用方法是将返回的错误与nil比较。 nil 值表示没有发生错误,非 nil 值表示存在错误。在我们的例子中,第 10 行检查了错误值是否为 nil。如果不是 nil,我们会简单地打印出错误,并在 main 函数中返回。

错误类型的内部实现

看看内置error类型是如何定义的。error是具有以下定义的接口类型:

type error interface {  
    Error() string
}

// http://golang.org/pkg/errors/error.go
// errors 构建 error 对象

type errorString struct {
    s string
}

func (e *errorString) Error() string {
    return e.s
}

error 有了一个签名为 Error() string 的方法。所有实现该接口的类型都可以当作一个错误类型。Error() 方法给出了错误的描述。
fmt.Println打印错误时,函数在内部调用该Error() string 方法以获取错误的描述。这就是在第 11 行错误描述中的打印方式。

使用New函数创建自定义错误

创建自定义错误的最简单方法是使用errors包的New函数

// Package errors implements functions to manipulate errors.
  package errors
 
  // New returns an error that formats as the given text.
  func New(text string) error {
      return &errorString{text}
  }
 
  // errorString is a trivial implementation of error.
  type errorString struct {
      s string
  }
 
  func (e *errorString) Error() string {
      return e.s
  }

实现非常简单。errorString是具有单个字符串s字段的结构类型。第 14 行使用了 errorString 指针接收器来实现 error 接口的 Error() string 方法。
第 5 行的 New() 函数有一个字符串参数,通过这个参数创建了 errorString 类型的变量,并返回了它的地址。于是它就创建并返回了一个新的错误。

在这里插入图片描述

Panic

有一些情况,程序在出现异常情况后无法继续执行。在这种情况下,我们使用panic提前终止程序。当一个函数遇到Panic时,它的执行被停止,任何延迟的函数都被执行,然后控制权返回给它的调用者。这个过程一直持续到当前goroutine的所有函数都返回,此时程序打印Panic消息,然后是堆栈跟踪,然后终止。

在这里插入图片描述
上面是一个打印人全名的简单程序。第 7 行的 fullName 函数会打印出一个人的全名。该函数在第 8 行和第 11 行分别检查了 firstName 和 lastName 的指针是否为 nil。如果是 nil,fullName 函数会调用含有不同的错误信息的 panic。当程序终止时,会打印出该错误信息。

recover

recover是一个内置函数,用于重新获得对Panic程序的控制权

func revocer() interface{}

仅当在延迟函数中调用时,Recover 才有用。在延迟函数中执行恢复调用会通过恢复正常执行来停止Panic序列,并检索传递给Panic函数调用的错误消息。如果在延迟函数之外调用恢复,它不会停止Panic序列。

修改上面的示例,并在Panic后使用恢复来恢复正常执行。
在这里插入图片描述
在这里插入图片描述
在第 7 行,recoverName() 函数调用了 recover(),返回了调用 panic 的参数。在这里,我们只是打印出 recover 的返回值(第 8 行)。在 fullName 函数内,我们在第 14 行延迟调用了 recoverNames()。

当 fullName 发生 panic 时,会调用延迟函数 recoverName(),它使用了 recover() 来阻止 panic 后续事件。

最佳实践

1.在错误处理时,尽量不要使用 panic 和 recover。只有当程序不能继续运行的时候,才应该使用 panic 和 recover 机制。
2.当 if err != nil 时及时返回错误,从而避免过多的代码嵌套。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值