你了解defer吗?
你了解defer吗?
代码如下:
1 |
|
问题:上面的代码会输出什么?为什么?
首先我们先来了解一下go语言中的defer:
defer顾名思义,延迟。它是go语言中的一个关键字,主要用在函数或方法前面,作用是用于函数和方法的延迟调用,在语法上,defer
与普通的函数调用没有什么区别。
在使用上非常简单,只需要弄清楚以下几点即可:
- 延迟的函数的什么时候被调用?
- 函数return的时候
- 发生panic的时候
- 延迟调用的语法规则
- defer关键字后面表达式必须是函数或者方法调用
- 延迟内容不能被括号括起来
- 当一个函数中有多个defer时,他们的执行顺序是先进后出
- 在函数执行return的过程可以分为三步:
- 设置返回值
- 执行defer语句
- 将结果返回
- defer 定义的延迟函数的参数在 defer 语句出时就已经确定下来了
知道了这些,上面的题目久很好理解了。
正确答案是 7。
当然,很有可能你的答案和正确答案一样,但分析不一定正确,所以接着往下看。
这里只对函数f
进行讲解:
- 首先使用defer关键字注册了一个匿名函数,然后这个匿名函数在
函数f
返回时执行。在这个匿名函数里,使用了recover()
,这意味着它可以恢复panic。- 接着定义了一个
变量f
,类型为func()
,这里由于只声明了,但是没有定义,故变量f
是一个nil
函数。- 然后使用defer关键字将
f变量
注册成延迟函数,这个延迟函数在函数f
返回时会执行,但这个匿名函数是一个nil函数
,因此在执行这个延迟函数时会触发panic- 接下来是对
变量f
的定义return n + 1
此时,返回值变量r = n + 1
,接着执行defer注册的延迟函数,因为defer函数的执行顺序是先进后出的,故先执行变量f
,但由于这里注册的是一个nil函数
,因此触发panic,接着执行最开始注册的匿名函数,此时r = n + 1 + n
,遇到了recover(),所以恢复了panic,将r的值返回- 最后返回给主函数的值
r = n + 1 + n = 7
你了解defer吗?
http://example.com/2023/04/18/Go每日一题/你了解defer吗?/