Tony Bai · Go 语言第一课
Tony Bai
资深架构师,tonybai.com 博主
21492 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 59 讲
开篇词 (1讲)
结束语 (1讲)
Tony Bai · Go 语言第一课
15
15
1.0x
00:00/00:00
登录|注册

22|函数:怎么结合多返回值进行错误处理?

思考题
错误处理策略
error接口类型
错误处理机制
Go函数设计与错误处理

该思维导图由 AI 生成,仅供参考

你好,我是 Tony Bai。
上一节课,我们开始了 Go 函数的学习,对 Go 语言中的函数已经有了基础的了解。那么,今天这节课,我们要再进一步,学习怎么做好函数设计。
在上节课的函数声明部分,我们提到,多返回值是 Go 语言函数,区别于其他主流静态编程语言中函数的一个重要特点。同时,它也是 Go 语言设计者建构 Go 语言错误处理机制的基础,而错误处理设计也是做函数设计的一个重要环节。
所以今天这节课,我们将会从 Go 语言的错误处理机制入手,围绕 Go 语言错误处理机制的原理、Go 错误处理的常见策略,来学习一下如何结合函数的多返回值机制进行错误处理的设计。
这会让你建立起 Go 编码的统一错误处理思维,写出更健壮的、让你自己更有信心的 Go 代码。
要想做好错误处理设计,我们首先要先来了解 Go 语言错误设计的基本思路与原理。

Go 语言是如何进行错误处理的?

采用什么错误处理方式,其实是一门编程语言在设计早期就要确定下来的基本机制,它在很大程度上影响着编程语言的语法形式、语言实现的难易程度,以及语言后续的演进方向。
我们前面已经多次提到,Go 语言继承了“先祖”C 语言的很多语法特性,在错误处理机制上也不例外,Go 语言错误处理机制也是在 C 语言错误处理机制基础上的再创新。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Go语言中的错误处理机制与多返回值的结合使用是本文的主要内容。文章首先介绍了Go语言错误处理的基本思路与原理,指出了Go语言继承了C语言的错误处理机制,并在此基础上进行了创新。与C语言不同的是,Go语言引入了多返回值机制,将错误状态与返回信息分离,建议开发者将它们分别放在不同的返回值中。文章还介绍了在Go语言中习惯使用error接口类型表示错误,并按惯例将error类型返回值放在返回值列表的末尾。此外,还介绍了Go语言中的错误值构造方法和透明错误处理策略,以及“哨兵”错误处理策略和错误值类型检视策略。值得注意的是,Go语言中还提供了错误行为特征检视策略,通过将某个包中的错误类型归类,统一提取出一些公共的错误行为特征,并将这些错误行为特征放入一个公开的接口类型中,从而降低了错误处理方与错误值构造方的耦合。总的来说,本文内容丰富,涵盖了Go语言错误处理的基本原理、多返回值机制、错误值构造方法以及多种错误处理策略,对于想要深入了解Go语言错误处理机制的读者来说,是一篇值得阅读的文章。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Tony Bai · Go 语言第一课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(32)

  • 最新
  • 精选
  • Digitalization
    这节课瞬间看不懂了,是不是最好先讲接口等其他知识点再讲这个呢?好像这节课跟函数没什么关系呀

    作者回复: 21讲已经覆盖的函数的基本语法,这一讲延展到函数设计之错误处理

    2022-02-10
    3
    12
  • 五彩斑斓的輝
    为什么内置的类型,如int、error等,首字母都是小写的,可以不用遵从首字母大写导出规则,到处都可以使用。是因为它们是在最外层的宇宙代码块里面声明的吗,这在实际上怎么实现的?

    作者回复: "是因为它们是在最外层的宇宙代码块里面声明的吗" - 是的。 这些预定义的类型由编译器特殊处理。

    2022-05-19
    6
  • 郑印
    如果函数调用太深,每次做返回值判断都需要写,if err != nil { return err; } 感觉会多出好多的模板代码,有什么好的解决办法吗?

    作者回复: 目前真的没有。

    2021-12-23
    2
    5
  • Geralt
    忽略错误算不算实用的策略呢

    作者回复: 上生产的代码务必不要忽略错误。

    2021-12-02
    5
  • 🦉
    请问文章这里 var e *MyError if errors.As(err, &e) { // 如果err类型为*MyError,变量e将被设置为对应的错误值 } &e是pointer e的地址吗?如果是的话为什么这样处理呢?谢谢

    作者回复: 对,&e是pointer e的地址。因为var err = &MyError{"MyError error demo"}中,err是一个MyError类型的指针,Error方法是*MyError类型的。 As函数要求,第二个参数应该是实现了error接口的类型的指针。这里*MyError实现了error接口,于是As的第二个参数应该是**MyError类型。 当然这个例子也可以改写一下: package main import ( "errors" "fmt" ) type MyError struct { e string } func (e MyError) Error() string { return e.e } func main() { var err = MyError{"MyError error demo"} err1 := fmt.Errorf("wrap err: %w", err) err2 := fmt.Errorf("wrap err1: %w", err1) var e MyError if errors.As(err2, &e) { println("MyError is on the chain of err2") println(e == err) return } println("MyError is not on the chain of err2") } 这样就不用传**MyError了,传*MyError了。因为新版中MyError也实现了error接口。

    2022-01-11
    2
    4
  • Witt
    if err != nil { return err; } 看错误怎么能少得了这个 🐶

    作者回复: 👍。

    2021-12-01
    10
    4
  • 在下宝龙、
    最后一部分的策略四的设计不是很懂 。。。

    作者回复: 问题再具体一些:)

    2021-12-01
    8
    4
  • aoe
    多值返回的错误处理很好用。知道了4种错误使用场景,变强了!

    作者回复: 👍

    2021-12-02
    3
  • Unknown element
    老师我想请教一下错误处理的策略二和策略三的区别是error具体的实现不同吗?哨兵错误处理策略相当于用的还是errorString,而错误值类型检视策略是自定义的struct,可以包含更多上下文?

    作者回复: 从机制上说:策略二是通过值比较进行判定,策略三是通过类型比较进行判定。 从功能上说:“基于 Go 标准库提供的错误值构造方法构造的“哨兵”错误值,除了让错误处理方可以“有的放矢”的进行值比较之外,并没有提供其他有效的错误上下文信息。那如果遇到错误处理方需要错误值提供更多的“错误上下文”的情况,上面这些错误处理策略和错误值构造方式都无法满足。”

    2022-10-25归属地:北京
    2
  • 冯仁彬
    感觉错误处理机制相对于Java没那么好用

    作者回复: 见仁见智:)

    2022-09-13归属地:辽宁
    3
    2
收起评论
显示
设置
留言
32
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部