左耳听风
陈皓
网名“左耳朵耗子”,资深技术专家
180940 人已学习
新⼈⾸单¥98
登录后,你可以任选6讲全文学习
课程目录
已完结/共 119 讲
左耳听风
15
15
1.0x
00:00/00:00
登录|注册

108 | Go编程模式:错误处理

第三方库:github.com/pkg/errors
使用接口暴露原始错误
使用fmt.Errorf包装错误
示例:Person结构体的读取和打印
使用结构体重构代码
函数式编程方式简化错误处理
代码示例:parse函数
Go语言的defer关键字
Java语言的finally语句块
C++语言的析构函数
C语言的goto fail方式
处理多种错误类型
自定义错误处理
忽略错误需要显式处理
参数作为入参,错误作为出参
多返回值
与状态返回码相比的优势
优点:清晰的接口语义、可读性、异常不可忽略、多态式的catch
异常处理机制
错误处理方式的问题
解决方案:strtol函数
问题:atoi函数的错误处理
错误码和errno
包装错误
Error Check Hell
资源清理
Go语言的错误处理
Java的错误处理
C语言的错误检查
Go 编程模式:错误处理

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

你好,我是陈皓,网名左耳朵耗子。
错误处理一直是编程必须要面对的问题。错误处理如果做得好的话,代码的稳定性会很好。不同的语言有不同的错误处理的方式。Go 语言也一样,这节课,我们来讨论一下 Go 语言的错误出处,尤其是那令人抓狂的 if err != nil
在正式讨论“Go 代码里满屏的 if err != nil 怎么办”这件事儿之前,我想先说一说编程中的错误处理。

C 语言的错误检查

首先,我们知道,处理错误最直接的方式是通过错误码,这也是传统的方式,在过程式语言中通常都是用这样的方式处理错误的。比如 C 语言,基本上来说,其通过函数的返回值标识是否有错,然后通过全局的 errno 变量加一个 errstr 的数组来告诉你为什么出错。
为什么是这样的设计呢?道理很简单,除了可以共用一些错误,更重要的是这其实是一种妥协,比如:read()write()open() 这些函数的返回值其实是返回有业务逻辑的值,也就是说,这些函数的返回值有两种语义:
一种是成功的值,比如 open() 返回的文件句柄指针 FILE*
另一种是错误 NULL。这会导致调用者并不知道是什么原因出错了,需要去检查 errno 以获得出错的原因,从而正确地处理错误。
一般而言,这样的错误处理方式在大多数情况下是没什么问题的,不过也有例外的情况,我们来看一下下面这个 C 语言的函数:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Go语言错误处理模式的文章总结: Go语言错误处理模式是本文的重点讨论内容。文章首先回顾了C语言和Java语言的错误处理方式,分别是通过错误码和异常来处理错误。然后详细介绍了Go语言的错误处理方式,强调了多返回值和显式错误处理的优势,以及使用defer关键词进行资源清理的特点。作者指出,Go语言的错误处理方式兼顾了返回值检查和异常的优点,使得函数接口语义清晰,错误不易被忽略,并且支持自定义错误处理。 文章还介绍了针对Go语言中常见的`if err != nil`代码处理方式的优化方法,包括使用函数式编程的闭包、结构体和成员函数的方式,以及错误包装的技巧。通过这些方法,可以使代码更加简洁清晰,减少大量的错误处理代码,提高代码的可读性和可维护性。 最后,文章提到了包装错误的重要性,建议将错误包装在另一个错误中,并保留原始内容,以便进一步检查。同时,介绍了通过接口实现`Cause()`方法来暴露原始错误的做法,以供进一步检查。这些技巧和最佳实践为读者提供了深入了解Go语言错误处理模式的指导。 总的来说,本文通过对比不同语言的错误处理方式,突出了Go语言的优势,并提供了优化代码和包装错误的实用技巧,适合帮助读者快速了解和应用于实际开发中。 文章内容丰富,涵盖了Go语言错误处理模式的方方面面,对于想深入了解和优化Go语言错误处理的读者来说,是一篇具有很高参考价值的文章。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《左耳听风》
新⼈⾸单¥98
立即购买
登录 后留言

全部留言(7)

  • 最新
  • 精选
  • 汪辉
    wrap和cause的错误包装在实际项目开发中非常有用,可以快速打印出错误栈,并根据err的类型做特殊处理,比如根据err级别进行不同的告警。我们这边常定义一个包含code和msg的struct,并实现Cause接口。出错的时候包上特定的错误码,最后根据Cause找出里面的错误码,设置不同的告警级别。
    2021-01-19
    16
  • @@fighting
    Go 语言最新的 errors 包给出了 %w 的方式,而不是 github.com/pkg/errors 这个包
    2021-04-01
    1
    6
  • AlphaGao
    『Go 语言的资源清理的示例:』这里的代码是不是重复了
    2021-03-29
    1
    2
  • Marvichov
    `Golang Error Handling lesson by Rob Pike` (http://jxck.hatenablog.com/entry/golang-error-handling-lesson-by-rob-pike) 的链接里面是日文的. 正确的链接应该是第二个reference的链接?
    2021-04-18
    1
  • 陌音
    这个errors库已经在2021年12月1号封存,不再维护了。现在有更好的替代吗?
    2023-03-31归属地:北京
  • Marvichov
    > There is one significant drawback to this approach, at least for some applications: there is no way to know how much of the processing completed before the error occurred. If that information is important, a more fine-grained approach is necessary. Often, though, an all-or-nothing check at the end is sufficient. 感觉应该加进`Error Check Hell` section. 不像exception, 你可以知道错在哪一步, this approach honors **all-or-nothing**
    2021-04-18
  • Marvichov
    nvm, the end of rob pike's article: > Finally, for the full story of my interaction with @jxck_, including a little video he recorded, visit his blog.
    2021-04-18
收起评论
显示
设置
留言
7
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部