为了账号安全,请及时绑定邮箱和手机立即绑定

当错误已返回时,从延迟函数返回错误

当错误已返回时,从延迟函数返回错误

Go
交互式爱情 2023-07-26 15:37:06
更新:我认为现在这个问题没有普遍的答案。我们可以使用答案中解释的技术返回这两个错误。我认为这里最重要的是不要忘记当我们有两个错误时的情况并以某种方式处理它。注意:SO上有很多关于如何从延迟函数返回错误的问题。这不是这里的问题。(在 Go 中)当函数已经返回错误时,从延迟函数返回错误的正确方法是什么。例如_func errorMaker() (err error) {    defer func() {        err = errors.New("Deferred error")    }()    err = errors.New("Some error")    return}func main() {    err := errorMaker()    fmt.Printf("Error: %v\n", err)}在上面的代码中,延迟函数返回的错误会覆盖该函数返回的错误。返回这两个错误的规范方法是什么?如果另一个程序员使用我的函数,当函数返回“两个错误”时,她期望从函数中得到什么结果?我应该为此使用错误包装吗?
查看完整描述

1 回答

?
茅侃侃

TA贡献1842条经验 获得超21个赞

免责声明:我不知道以下建议是否可以被视为“标准”或“广泛接受”。

我应该为此使用错误包装吗?

简短的回答:是的(我会这样做)。


Go 1.12 及更早版本

当我需要错误来传达某些特定含义时,我会做什么,而不放弃接口error,我创建一个实现错误接口的包装器 - Error() string-。该包装包含我需要的所有额外信息。

如果调用者知道这些额外信息的存在,它可以通过强制转换来解开错误并找到这些信息。额外的好处是,不知情的调用者可以将错误作为通用的error.

type MyError struct {

    DeferredError error

}


// Implements 'error' interface

func (e MyError) Error() string {

    // format to string

}


func someFunc() error {

    // might return an instance of MyError

}


...


// Caller code

err := someFunc()

if err != nil {

    if myErr, ok := err.(*MyError); ok {

        // here you can access the wrapped info

        fmt.Println(myErr.DeferredError)


    } else {

        // otherwise handle the error generically

    }

}

转到 1.13 及以上

使用 Go.13,您可以用来errors.As解开错误。来自官方文档:


[方法] As 查找 err 链中与 target 匹配的第一个错误,如果是,则将 target 设置为该错误值并返回 true。该链由 err 本身和通过重复调用 Unwrap 获得的错误序列组成。


var myErr *MyError

if errors.As(err, &myErr) {

    // here you can access the wrapped info

    fmt.Println(myErr.DeferredError)

} else {

    // otherwise handle the error generically 

}

正如文档所说,该myErr变量是作为调用的副作用而填充的As。


查看完整回答
反对 回复 2023-07-26
  • 1 回答
  • 0 关注
  • 68 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信