Chinaunix首页 | 论坛 | 博客
  • 博客访问: 491834
  • 博文数量: 28
  • 博客积分: 858
  • 博客等级: 一等列兵
  • 技术积分: 852
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-02 14:13
文章分类

全部博文(28)

文章存档

2020年(1)

2019年(1)

2018年(5)

2017年(1)

2014年(1)

2013年(2)

2012年(17)

分类: LINUX

2019-04-17 16:09:11

    errors是用的最多的一个package,go doc上面显示有202948个package使用了errors。我相信只有使用go写程序,基本上都会用到这个库。每一个编程语言都离不开错误处理的话题。
    Java 通过catch…exception结构来处理错误。

    C语言通过函数返回值,来表示函数执行情况。默认是返回0,表示成功,非0表示失败。

    Go 同样通过函数返回值来表示函数的执行情况。Nil表示函数执行成功,非nil表示函数执行失败。
那么go如何表示应用程序的错误,这其实就是errors库的作用。这里我们假设一个函数的定义如下:


点击(此处)折叠或打开

  1. func TestFunc(a int) (int, error)
我们看返回值部分,他返回两部分,一部分是函数的返回值,另一个是函数的错误。这里我们假设函数按预期执行返回nil,出现问题返回非nil。那么非nil怎么表示?这个非nil其实我们有以下要求:
  1. 能够明确说明函数执行碰到了什么问题。
  2. 可以与nil做比较。
首先我们看error到底是个什么东西?

点击(此处)折叠或打开

  1. type error interface {
  2. Error() string
  3. }
它其实是一个接口类型,要求是要实现Error()string 方法。
标准库介绍里只提到了New函数, 他返回一个errorString结构体的指针,这个类型实现了Error方法。这一个函数就可以让我们轻松面对我们的日常开发。

点击(此处)折叠或打开

  1. type errorString struct {
  2. s string
  3. err error
  4. frame Frame
  5. }

点击(此处)折叠或打开

  1. func (e *errorString) Error() string {
  2. if e.err != nil {
  3. return e.s + ": " + e.err.Error()
  4. }
  5. return e.s //自定义的会返回这个
  6. }

点击(此处)折叠或打开

  1. func New(text string) error {
  2. // Inline call to errors.Callers to improve performance.
  3. var s Frame
  4. runtime.Callers(2, s.frames[:])
  5. return &errorString{text, nil, s}//自定义的err总为nil
  6. }

生成error的方式
1. 自定义类型,实现Error方法

点击(此处)折叠或打开

  1. mkdir -p $GOPATH/src/github.com/errors-example
  2. cd $GOPATH/src/github.com/errors-example
  3. touch errorsExample.go

点击(此处)折叠或打开

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. type MyError struct {
  7. When time.Time
  8. What string
  9. }
  10. func (e *MyError) Error() string {
  11. return fmt.Sprintf("%v:%v", e.When, e.What)
  12. }
  13. func oops() error {
  14. return &MyError{
  15. time.Date(1989, 3, 15, 22, 30, 0, 0, time.UTC),
  16. "the file system has gone away",
  17. }
  18. }
  19. func main() {
  20. if err := oops(); err != nil {
  21. fmt.Println(err)
  22. }
  23. }
这里定义了一个结构体MyError,包涵一个时间,一个字符串,实现了Error方法,返回时间戳和字符串。 那么它符合error接口的定义,所以可以是一个error。
2. 使用New函数,生成标准error

点击(此处)折叠或打开

  1. err := errors.New("emit macho dwarf: elf header corrupted")
  2. if err != nil {
  3.     fmt.Print(err)
  4. }
3. 使用fmt包中的Errorf生成error

点击(此处)折叠或打开

  1. const name, id = "bimmler", 17
  2. err := fmt.Errorf("user %q (id %d) not found", name, id)
  3. if err != nil {
  4. fmt.Print(err)
  5. }
总结:合适的错误定义,可以使我们的思路和代码清晰。






阅读(7465) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~