uG环球色碟
Go Error 的野心玄学是 「Errors Are Values」。
iba骰宝这句话应该怎样相连呢?翻译起来挺难的。不外从源码的角度来看,冒失更容易相连其背后的含义。
皇冠信用怎么开Go Error 源码很浅近,寥寥几行:
// uG环球色碟src/builtin/builtin.go type error interface { Error() string }
error 是一个接口类型,只需要竣事 Error() 方法即可。在 Error() 方法中,就不错复返自界说结构体的轻易施行。
底下率先说说怎样创建 error。
皇冠博彩 创建 Error创建 error 有两种样式,分散是:
errors.New(); fmt.Errorf()。 errors.New()errors.New() 的使用不竭了 Go 的一贯立场,New 一下就不错了。
举一个例子:
package main import ( "errors" "fmt" ) func main() { err := errors.New("这是 errors.New() 创建的造作") fmt.Printf("err 造作类型:%T,造看成:%v\n", err, err) } /* 输出 err 造作类型:*errors.errorString,造看成:这是 errors.New() 创建的造作 */
这段代码独一让东说念主困惑的所在可能即是造作类型了,但不进击。只排场一下源码,就短暂理丝益棼。
源码如下:
// src/errors/errors.go // New returns an error that formats as the given text. // Each call to New returns a distinct error value even if the text is identical. 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 是一个结构体,竣事了 Error() 方法,New 函数平直复返 errorString 指针。
这种用法很浅近,但乌灵验。假如我还念念复返门径的高下文信息,它就没辙了。
底下看第二种样式。
fmt.Errorf()依然先看一个例子:
package main import ( "database/sql" "fmt" ) func foo() error { return sql.ErrNoRows } func bar() error { return foo() } func main() { err := bar() if err == sql.ErrNoRows { fmt.Printf("data not found, %+v\n", err) return } if err != nil { fmt.Println("Unknown error") } } /* 输出 data not found, sql: no rows in result set */
这个例子输出了咱们念念要的服从,可是还不够。
一般情况下,咱们和会过使用 fmt.Errorf() 函数,附加上咱们念念添加的文本信息,使复返施行更明确,处理起来更活泼。
是以,foo() 函数会改成底下这么:
func foo() error { return fmt.Errorf("foo err, %v", sql.ErrNoRows) }
这时问题就出现了,流程 fmt.Errorf() 的封装,原始 error 类型发生了改革,这就导致 err == sql.ErrNoRows 不再开采,复返信息酿成了 Unknown error。
如若念念凭据复返的 error 类型作念不同处理,就无法竣事了。
因此,Go 1.13 为咱们提供了 wrapError 来处理这个问题。
Wrap Error看一个例子:
package main import ( "fmt" ) type myError struct{} func (e myError) Error() string { return "Error happended" } func main() { e1 := myError{} e2 := fmt.Errorf("E2: %w", e1) e3 := fmt.Errorf("E3: %w", e2) fmt.Println(e2) fmt.Println(e3) } /* output E2: Error happended E3: E2: Error happended */
乍一看冒失好没什么区别,但背后的竣事旨趣却并不调换。
球衣文化Go 延长了 fmt.Errorf() 函数,欧博娱乐城增多了一个 %w 记号符来创建 wrapError。
// src/fmt/errors.go func Errorf(format string, a ...interface{}) error { p := newPrinter() p.wrapErrs = true p.doPrintf(format, a) s := string(p.buf) var err error if p.wrappedErr == nil { err = errors.New(s) } else { err = &wrapError{s, p.wrappedErr} } p.free() return err }
当使用 w% 时,函数会复返 &wrapError{s, p.wrappedErr},wrapError 结构体界说如下:
// src/fmt/errors.go type wrapError struct { msg string err error } func (e *wrapError) Error() string { return e.msg } func (e *wrapError) Unwrap() error { return e.err }
竣事了 Error() 方法,评释它是一个 error,而 Unwrap() 方法是为了取得被封装的 error。
皇冠hg86a
// src/errors/wrap.go func Unwrap(err error) error { u, ok := err.(interface { Unwrap() error }) if !ok { return nil } return u.Unwrap() }
它们之间的关联是这么的:
皇冠客服飞机:@seo3687
紫皇冠api因此,咱们不错使用 w% 将上文中的门径进行更动,使其施行输出更丰富。
在最近的一场比赛中,体育明星内马尔在赛场上的争议表现引起了很多人的关注。一些球迷指责他在比赛中虚假倒地,试图诱使裁判给自己的队伍罚点球。然而,内马尔的支持者则认为这只是他敏锐的战术意识在发挥。如下:
package main import ( "database/sql" "errors" "fmt" ) func bar() error { if err := foo(); err != nil { return fmt.Errorf("bar failed: %w", foo()) } return nil } func foo() error { return fmt.Errorf("foo failed: %w", sql.ErrNoRows) } func main() { err := bar() if errors.Is(err, sql.ErrNoRows) { fmt.Printf("data not found, %+v\n", err) return } if err != nil { fmt.Println("Unknown error") } } /* output data not found, bar failed: foo failed: sql: no rows in result set */
终于有了让东说念主平稳的输出服从,每个函数齐增多了必要的高下文信息,况兼也合适对造作类型的判断。
errors.Is() 函数用来判断 err 以过甚封装的 error 链中是否包含指标类型。这也就贬责了上文提倡的无法判断造作类型的问题。
跋文其实,Go 当今对 Error 的处理样式亦然充满争议的。不外,官方团队正在积极和社区交流,提倡创新方法。信服在不久的改日,一定会找到更好的贬责决策。
现阶段来说,大部分团队可能会遴荐 github.com/pkg/errors 包来进行造作处理。如若感有趣的话,不错学学看。
皇冠信用登录网址好了,本文就到这里吧。关心我,带你通扰乱题读 Go 源码。
源码地址:https://github.com/yongxinz/gopher
参考著述:
https://chasecs.github.io/posts/the-philosophy-of-go-error-handling/
网站地区限制说明https://medium.com/@dche423/golang-error-handling-best-practice-cn-42982bd72672
当前,无论是罔顾事实地拿中国说事,还是颠倒黑白地拿中美关系说事,都已成了美国拜登政府高级官员炉火纯青的必备技能,一个接一个的表演,重复着美国政客那套“一瞒、二横、三搅、四甩”的老套路,继续说出那些老掉牙的陈词滥调。这不,在白宫安全顾问沙利文刚刚唱罢之际,美国国务卿布林肯马上就迫不及待地粉墨登场了。
https://www.flysnow.org/2019/09/06/go1.13-error-wrapping.html