亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

不一致的錯誤:換行 / 錯誤 - 展開 / fmt.Errorf(%w)

不一致的錯誤:換行 / 錯誤 - 展開 / fmt.Errorf(%w)

Go
一只萌萌小番薯 2022-10-24 08:58:28
fmt.Errorf使用with%w和 using包裝錯誤之間似乎存在不一致errors.Wrap:    e1 := errors.New("error1")    efmt := fmt.Errorf("error2: %w", e1)    eerr := errors.Wrap(e1, "error2")    fmt.Println(errors.Unwrap(efmt))       // error1    fmt.Println(errors.Unwrap(efmt) == e1) // true    fmt.Println(errors.Unwrap(eerr))       // error2: error1    fmt.Println(errors.Unwrap(eerr) == e1) // false :-(此處提供了完整示例我不確定這是否是有意的,但這似乎不一致......有什么理由嗎?這在任何地方都有記錄嗎?
查看完整描述

1 回答

?
繁華開滿天機

TA貢獻1816條經驗 獲得超4個贊

這是預期的工作,這不違反文檔。多個錯誤可能包含在單個error值中,并且由于調用Unwrap()返回單個錯誤,顯然沒有得到您期望的內容并不意味著沒有包含預期的錯誤。


該errors軟件包來自標準庫。它沒有errors.Wrap()功能。您使用的是 from github.com/pkg/errors.Wrap(),它在引擎蓋下進行“雙重包裝”。


首先它用給定的錯誤消息包裝錯誤,然后再次包裝以保留堆棧信息:


// Wrap returns an error annotating err with a stack trace

// at the point Wrap is called, and the supplied message.

// If err is nil, Wrap returns nil.

func Wrap(err error, message string) error {

    if err == nil {

        return nil

    }

    err = &withMessage{

        cause: err,

        msg:   message,

    }

    return &withStack{

        err,

        callers(),

    }

}

當您調用時Unwrap(),將返回來自第二次包裝的錯誤(這不是原始錯誤,而是包裝原始錯誤的包裝錯誤),Unwrap()再次調用將返回原始錯誤。


fmt.Println("Double unwrap:",

    errors.Unwrap(errors.Unwrap(err2wrp)) == err1)

這就是為什么你應該使用errors.Is()來避免這種“怪癖”:


fmt.Println("Proper use:", errors.Is(err2wrp, err1))

在Go Playground上試試這些。

請注意,以上報告true是您調用github.com/pkg/errors.Is()還是標準庫的errors.Is().


查看完整回答
反對 回復 2022-10-24
  • 1 回答
  • 0 關注
  • 119 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號