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

23|函数:怎么让函数更简洁健壮?

知晓defer带来的性能损耗
注意defer关键字后面表达式的求值时机
明确哪些函数可以作为deferred函数
不要混淆异常与错误
提示潜在bug
评估程序对panic的忍受度
捕捉和恢复panic的方法:recover函数
panicking过程
Go中的异常由panic表示
defer使用的几个注意事项
defer的运作机制
如何应对panic
认识Go语言中的异常:panic
不要假定异常不会发生
不要忽略任何一个错误
不要相信任何外部输入的参数
使用defer简化函数实现
Go函数的异常处理设计
"三不要"原则
使用defer的小技巧
简洁性
健壮性
思考题
函数设计
总结

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

你好,我是 Tony Bai。
在上一节中,我们开始学习函数设计的相关知识,学习了如何基于 Go 函数的多返回值机制进行函数错误值构造方式的设计,你还记得那几种错误值构造与处理的策略吗?当然,良好的函数设计不仅仅要包含错误设计,函数的健壮性与简洁优雅也是我们在函数设计过程中要考虑的问题。
健壮的函数意味着,无论调用者如何使用你的函数,你的函数都能以合理的方式处理调用者的任何输入,并给调用者返回预设的、清晰的错误值。即便你的函数发生内部异常,函数也会尽力从异常中恢复,尽可能地不让异常蔓延到整个程序。而简洁优雅,则意味着函数的实现易读、易理解、更易维护,同时简洁也意味着统计意义上的更少的 bug。
这一节课,我们就将继续我们的函数设计之旅,聚焦在健壮与简洁这两方面,我们需要重点关注的内容。
我们先从健壮性开始。

健壮性的“三不要”原则

函数的健壮性设计包括很多方面,首先就有最基本的“三不要”原则,我们简单来分析一下。
原则一:不要相信任何外部输入的参数。
函数的使用者可能是任何人,这些人在使用函数之前可能都没有阅读过任何手册或文档,他们会向函数传入你意想不到的参数。因此,为了保证函数的健壮性,函数需要对所有输入的参数进行合法性的检查。一旦发现问题,立即终止函数的执行,返回预设的错误值。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Go函数设计需要考虑健壮性与简洁优雅。本文深入讨论了Go函数设计中的健壮性与异常处理,强调了评估程序对panic的忍受度的重要性,以及使用panic提示潜在bug的方法。此外,文章介绍了defer的运作机制和使用注意事项,以及对Go函数设计和实现的简化作用。通过具体的代码示例和对比分析,读者可以获得宝贵的设计原则和实践建议,包括如何评估程序对panic的忍受度、使用panic提示潜在bug以及避免混淆异常与错误的重要性。此外,文章还提到了Go 1.17版本中defer的性能优化,使得其开销几乎可以忽略不计。总之,本文为读者提供了关于Go函数设计的重要原则和实用技巧,对于开发人员在实际开发中提供了有益的指导和启发。

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

全部留言(32)

  • 最新
  • 精选
  • 进化菌
    panic 恐慌,慌慌张张的抛出异常;recover 恢复,淡定还有事情要做,先别退出;defer 延迟,晚点要做的事情不能忘……

    作者回复: 👍

    2021-12-06
    2
    23
  • helloxiaomin
    defer的使用技巧:1)defer要在panic之前,才能执行;2)defer内部的recover只能捕获当前协程的Panic,不能跨协程执行;3)recover只能在defer中调用才能生效。暂时想到这些

    作者回复: 👍

    2021-12-07
    16
  • return
    老师讲的太好了, 再请教一下老师, panic应该在什么场景下使用, 感觉平时 业务代码 使用 err足够,没有使用panic的场景, 文中举例的 http server比较合适, 但是json encode,虽然官方用了panic,但是个人感觉 使用err也没毛病, 传入的 json串 有问题嘛,就是 入参校验err呗。 所以 get 不到 什么情况下用 panic。

    作者回复: 如果在平时panic用的,那么就说明你走在了正确的道路上:)。panic本身就是异常,异常本身就是很少发生的。目前看panic最常使用的就是充当“断言”,提示潜在bug时用的最多。

    2021-12-06
    5
    14
  • liaomars
    看了官方标准库的defer说明,发现一个tips是:可以跟踪函数的执行过程

    作者回复: 可以的。在后面的一个实战项目中,我们就会应用到这一点。

    2021-12-06
    3
    11
  • 请教一个非课程的问题: v := [...]int{1: 2, 3: 4} fmt.Println(len(v)) 这里为什么打印出来的 长度是 4呢?

    作者回复: 这是一种通过数组下标方式对数组进行初始化的方式。我记得我在第15讲中提到过吧。这里数组字面值中最大的下标值为3,go编译器就认为数组长度是4.(下标值范围0~3)

    2021-12-07
    6
    8
  • lesserror
    感谢 Tony Bai 老师关于defer的深入讲解,不过我想问一下,在for中使用defer函数,编辑器会提示可能造成资源泄露,能大致说明一下这块儿的知识吗?

    作者回复: defer是在函数退出时调用的。如果在for语句的每个迭代都使用defer设置deferred函数,这些deferred函数会压入runtime实现的defer列表中。会占用内存资源,并且如果for的loop次数很多,这个消耗将很可观。文中在for中使用defer仅是为了举例而已。生产代码这块的确要谨慎,通常是没有必要这么做的。

    2021-12-07
    2
    5
  • van
    panic作为断言使用,上一层的调用者还是需要自己recover回来吧,不然这个调用链会最终传到main函数

    作者回复: 把panic当做断言使用的目的是及早发现bug,一旦断言发生,意味着整个程序出现了不可恢复的状态。对于这类panic,不要recover。尽早失败并解决bug。所以在什么位置进行断言,对哪些条件进行断言是需要考量的。在C语言中使用assert也是同样的道理。一旦assert失败,便会dump core文件。程序终止。

    2022-04-28
    3
  • ゝ骑着小车去兜风。
    老师你好,没太明白闭包的原理,想不明白为什么输出的是4,请帮忙解答下

    作者回复: 循环结束后,i的值为4. defer输出的是i的值,于是就都是4.

    2022-01-06
    3
    3
  • 功夫熊猫
    defer数据库的开关。锁的申请释放。TCP的连接和断开之类的

    作者回复: 👍

    2021-12-11
    3
  • 宋世杰
    Defer函数被放在一个不同于主函数的函数栈中吗? 是用slice实现的吗?

    作者回复: 是go runtime层实现的。

    2021-12-06
    4
    3
收起评论
显示
设置
留言
32
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部