Go聖經-學習筆記之error接口

上一篇 Go聖經-學習筆記之http.Handler接口git

下一篇 Go聖經-學習筆記之併發循環github

error接口定義

初學者通常使用error的方法:err:= errors.New("xxx"); fmt.Println(err.Error()),咱們如今看一下error接口定義:golang

type error interface {
    Error() string
}

Go語言默認實現了一個error接口,纔有了初學者簡單使用errors.New函數併發

package errors

func New(text string) { &errorString{text} }

type errorString struct {
    text string
}

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

正由於在errors標準庫實現了一個默認的error接口,咱們就可使用默認的錯誤處理,返回錯誤信息。函數

這裏要注意一點,有時候會犯錯誤,可能有些開發者會碰到下面這種狀況。學習

func xxx(xxx, xxx) (retCode int, err error)
if err == err1 {
    retCode = consts.DB__READ_ERROR
} else if err == err2 {
    retCode = consts.DB__INSERT_ERROR
}
return

上面的返回結果有時候err不爲空,可是retCode=0;有時候是正確的結果:err不爲空,retCode也爲0。.net

這是由於存在兩種狀況:日誌

  • err1和err2是全局變量接口對象值,而err是從某個接口返回的err1或者err2的接口值引用,因此上面的代碼能夠正確校驗;
  • 若是err1和err2,與err不是引用獲取的,則須要用到下面的方法進行校驗

第一種方式,常常看到一些開發者這樣作的:code

ErrTxHasBegan    = errors.New("<Ormer.Begin> transaction already begin")
    ErrTxDone        = errors.New("<Ormer.Commit/Rollback> transaction not begin")
    ErrMultiRows     = errors.New("<QuerySeter> return multi rows")
    ErrNoRows        = errors.New("<QuerySeter> no row found")
    ErrStmtClosed    = errors.New("<QuerySeter> stmt already closed")
    ErrArgs          = errors.New("<Ormer> args error may be empty")
    ErrNotImplement  = errors.New("have not implement")
    
    // 預先定義好全部的業務邏輯錯誤,而後直接返回這些錯誤接口值的引用

第二種方式,比較low,直接是比較錯誤日誌信息。orm

func xxx(xxx, xxx) (retCode int, err error)
    if err !=nil {
        if err.Error() == err1.Error() {
            retCode = consts.DB__READ_ERROR
        } else if err.Error() == err2.Error() {
            retCode = consts.DB__INSERT_ERROR
        }
    }
    return
}

大多數開發者通常先定義業務邏輯錯誤接口值,而後引用這些錯誤值,就能夠直接進行比較了。

注意一點, 接口值可不能夠比較,主要看接口類型中的各個元素是否是能夠比較的?就相似於struct能不能比較,就看struct的各個元素可不能夠比較?

  • 它是在編譯時肯定的。
  • 若是編譯時肯定不了,且不能夠比較,那就只能在運行時panic了

咱們通常比較少的直接使用errors.New, 它通常用於標準庫內部Wrap使用。例如:

package fmt
func Errorf(format string, a ...interface{}) error {
    return errors.New(fmt.Sprintf(format, a...))
}

// 或者之前提過的一個github上的errors包:github.com/pkg/errors
func Errorf(format string, args ...interface{}) error {
    return &fundamental{
        msg:   fmt.Sprintf(format, args...),
        stack: callers(),
    }
}
相關文章
相關標籤/搜索