defer注册未初始化函数

题目:

下面这段代码输出什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func f(n int) (r int) {
defer func() {
r += n
recover()
}()

var f func()

defer f()
f = func() {
r += 2
}
return n + 1
}

func main() {
fmt.Println(f(3))
}

答案及解析

​ 输出 7 。

​ 知识点:在 defer 注册函数的时候,即使注册了未初始化的函数,也不会报错,会继续执行后面的语句。

​ 当函数返回时,执行 defer 函数的时候,如果执行到了 未初始化的函数,就会发生 panic,并继续执行完其他 defer。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func main() {
var f func()

defer func() {
fmt.Println("...")
//recover() //恢复 panic
}()
defer f() // 注册一个未初始化的函数

fmt.Println("注册成功")
f = func() {
fmt.Println("Deferred function")
}

fmt.Println("初始化成功")
}

在本题中,将参数 3 传入函数 f ,此时 n = 3,注册两个 defer 函数,然后返回 n + 1,此时 r = n + 1 = 4。

先执行 f() 函数,由于注册的时候该函数未进行初始化,故执行时发生 panic ,然后执行剩余的一个 defer 函数,此时 r = n + r = 7,然后 recover() 恢复了 panic ,使得函数能够执行最后一步,将 r 返回给 主函数 main,即 7。


defer注册未初始化函数
http://example.com/2023/08/07/Go每日一题/defer注册未初始化函数/
作者
Feng Tao
发布于
2023年8月7日
更新于
2023年8月7日
许可协议