Golang中的错误处理

error是个啥

Golang的error是一个接口:

type error interface {
        Error() string
}

也就是说,实现了 Error() string 就可以。

errors

看看标准库里的errors咋用:

package main

import (
	"errors"
	"fmt"
)

// MyError 就是一个自定义的错误
type MyError struct{}

func (e MyError) Error() string {
	return "my error instance"
}

func oops() error {
	return MyError{}
}

func oops2() error {
	return errors.New("hoho")
}

func checkError(err error) {
	switch err.(type) {
	case MyError:
		fmt.Printf("MyError happened: %s\n", err)
	default:
		fmt.Printf("errors happend: %#v\n", err)
	}
}

func main() {
	checkError(oops())
	checkError(oops2())
}

执行一下:

$ go run main.go
MyError happened: my error instance
errors happend: &errors.errorString{s:"hoho"}

我们发现,标准库里的errors只能保存一个字符串,看下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
}

有时候我们想要把调用栈也打印出来,如果只使用errors的话,我们就要每次自己把栈封装进去:

package main

import (
	"fmt"
	"runtime/debug"
)

// MyError 就是一个自定义的错误
type MyError struct {
	s     string
	stack []byte
}

// NewMyError 新建错误
func NewMyError(s string) error {
	return MyError{s, debug.Stack()}
}

func (e MyError) Error() string {
	return fmt.Sprintf("%s\n%s", e.s, e.stack)
}

func main() {
	fmt.Printf("%s\n", NewMyError("hello"))
}

不过已经有库了,推荐使用 https://github.com/pkg/errors,也可以坐等 Go2: https://go.googlesource.com/proposal/+/master/design/go2draft.md



微信公众号
关注公众号,获得及时更新

更多文章
  • Web开发系列(一):从输入网址到最后,这个过程经历了什么?
  • SNI: 让Nginx在一个IP上使用多个证书
  • Haskell: infixl, infixr, infix
  • Haskell简明教程(五):处理JSON
  • Haskell简明教程(四):Monoid, Applicative, Monad
  • HTTPS 的详细流程
  • OAuth2 为什么需要 Authorization Code?
  • 任务队列怎么写?python rq源码阅读与分析
  • XMonad 配置教程
  • Haskell简明教程(三):Haskell语法
  • Haskell简明教程(二):从命令式语言进行抽象
  • Haskell简明教程(一):从递归说起
  • 2017年必装的VIM插件推荐
  • TCP/IP简明教程 - 从零构建TCP/IP协议(二)连接,断开与拥塞控制
  • TCP/IP简明教程 - 从零构建TCP/IP协议(这次叫PCT协议)