文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

为什么 Go 返回一个指向错误包装器的指针,但用“error”而不是“*error”声明它

2024-02-10 05:21

关注

为什么 Go 返回一个指向错误包装器的指针,但用“error”而不是“error”声明它?这是一个常见的问题,许多 Go 语言开发者都会遇到。简单地说,Go 返回错误的方式是为了方便使用和处理错误。在 Go 中,错误是一个接口类型,它有一个 Error() 方法来返回错误消息。因此,当函数返回一个错误时,实际上是返回一个实现了 Error() 方法的结构体指针。这种设计使得错误处理变得更加简洁和灵活,减少了代码的冗余和复杂性。因此,虽然返回一个指针可能看起来有些奇怪,但它实际上是为了提供更好的错误处理机制。

问题内容

我正在从 Java 背景学习 Go 语言。

type MyError struct {
    message string
    Offset  int
}

func (Me *MyError) Error() string {
    return Me.message
}

func myFunction() (int, error) {      <-- Why the return type is "error" rather than "*error"
    return 0, &MyError{"my error message", 0} <-- The error is returned as a pointer.
}

func main() {
    var _, err = myFunction()
    if e, ok := err.(*MyError); ok {.  <-- Why I can assert err which is a type of "error" into a pointer
        fmt.Printf("Error is %s: %d\n", e.message, e.Offset)
    }
}

在上面的代码中,我不明白为什么myFunction的错误类型是“error”而不是“*error”?我清楚地在下面的行中返回了一个指向 MyError 结构的指针。

我也明白为什么我可以将主函数中的错误断言回指针。

解决方法

要了解 Go 中的传统错误处理,您应该首先了解该语言中的接口如何工作。在谈论 Go 接口时需要记住两件事:

  1. Go 中的接口定义了一组方法(从 Go1 开始.18 也是一组类型)。在幕后,Go 接口包含两个元素,类型 T 和值 VV 始终是具体类型,例如 intstruct 或指针,而不是接口本身。

  2. Go 中没有 implements 关键字。 Go 类型通过实现该接口的方法来满足该接口。这称为隐式实现。

错误处理

Go 定义了一个内置的 error 类型,它只是一个接口:

type error interface {
    Error() string
}

事实上,它没有什么特别之处,除了它是一个全局预声明类型。该类型通常用于错误处理。

以您的示例为例:

func myFunction() (int, error) {
    return 0, &MyError{"my error message", 0}
}

func main() {
    var _, err = myFunction()
    if e, ok := err.(*MyError); ok {
        fmt.Printf("Error is %s: %d\n", e.message, e.Offset)
    }
}

指向 MyError 的指针和 error 接口之间的关系发生在幕后,您不需要显式返回 *error 即可从 MyError 值引用 error (实际上,您 几乎永远不需要指向接口的指针)。

返回 myFunction 后,error 值将保存以下元组 (V=&MyError{message: "my error message", Offset: 0}, T=*MyError),其中 V 是它的值保持,T 是值 V 的类型。

因为 Go 允许您在接口值上键入断言。基本上,您要问的 Go 操作 e, ok := err.(*MyError) 是: err 值(哪种类型是 error 接口)是否将类型 *MyError 作为其底层 T?如果是这样,则 ok 将是 true,并且 e 将接收其底层 V&MyError{message: "我的错误消息", Offset: 0}

注意:请谨慎对待 nil 错误值,因为它们可能并不总是由于界面的细微差别,其行为符合预期。

以上就是为什么 Go 返回一个指向错误包装器的指针,但用“error”而不是“*error”声明它的详细内容,更多请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯