Go每日一题 今日(2025-02-13) 的题目如下

3901 次点击 · 5 赞 ·大约8小时之前 开始浏览   · 来源「Golang来啦」

下面这段代码输出什么?

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))
}
3901 阅读
49 回复
minQie
minQie · #1 · 3年之前

di

henry1
henry1 · #2 · 3年之前

到-求讲解

feiyang
feiyang · #3 · 3年之前

好难,不懂

neil_liu
neil_liu · #4 · 3年之前

mark

Inforleo
Inforleo · #5 · 3年之前

m

brunce
brunce · #6 · 3年之前

来个大哥解释一下

halo_young
halo_young · #7 · 3年之前

m

chao1992
chao1992 · #8 · 3年之前

应该是defer注册延迟执行函数时, f 未初始化, 为nil, f()会panic, r += 2不会执行, 若把defer f()与f = func() {r += 2}换一下位置, 值就是9了

liangmanlin
liangmanlin · #9 · 3年之前

6楼 @brunce


// 先执行这一段代码, 然后 r 被赋值为 4
return n+1

// 然后执行,但是会触发panic
defer f()

// 最后执行,r 再加3 r=7,然后recover(),最后函数返回 7
defer func() {
        r += n
        recover()
    }()
Dessert
Dessert · #10 · 3年之前

同求讲解

Skysolderone
Skysolderone · #11 · 3年之前

mark

577961141
577961141 · #12 · 3年之前

个人见解:

  1. 考察了defer的调用,通过上面的defer f()可知,f()是没有定义的?(存疑)所以报了panic,而在defer func()里面的recover()处理了这个panic,保证了整个程序能够执行完
  2. 然后看f()函数返回的值为r,而不是n+1,这里考察的是函数的返回这一块的知识,所以最后的结果不是return n+1而是n+1+n的结果(第三点详细解释)
  3. 为什么会等于7?看看最f()函数的最后一行为return n+1,也就是return 3+1,函数f()的返回参数为r int,所以r = 3 + 1,再到defer func()r+=n也就是r = n + 1 + nr = 3 + 1 + 3,然后返回r的值,就是7
shunuanwei
shunuanwei · #13 · 3年之前

我现在想问一下,为什么出现panic,或者 panic的问题在哪里。。。 求大神指教!!!!

johann1024
johann1024 · #14 · 3年之前

2022-04-25

dingweihua
dingweihua · #15 · 3年之前

可以参考 https://studygolang.com/articles/27408 对于defer的知识点

dingweihua
dingweihua · #16 · 3年之前

这个题目很有意思,如果把defer f()这一行改为f(),返回值就会变为3

Natsuwau
Natsuwau · #17 · 3年之前

mark

TimLiuDream
TimLiuDream · #18 · 3年之前

mark

NovaChaos
NovaChaos · #19 · 3年之前

mk

hasbug
hasbug · #20 · 3年之前

mark

abcdhope
abcdhope · #21 · 3年之前

defer与panic

_Aiden_
_Aiden_ · #22 · 3年之前

有意思

Dessert
Dessert · #23 · 3年之前
liangmanlinliangmanlin #9 回复

6楼 @brunce ```golang // 先执行这一段代码, 然后 r 被赋值为 4 return n+1 // 然后执行,但是会触发panic defer f() // 最后执行,r 再加3 r=7,然后recover(),最后函数返回 7 defer func() { r += n recover() }() ```

mingtop
mingtop · #24 · 3年之前

需要脑补知识点。。。

euibieur894
euibieur894 · #25 · 3年之前
577961141577961141 #12 回复

个人见解: 1. 考察了defer的调用,通过上面的```defer f()```可知,f()是没有定义的?(存疑)所以报了panic,而在`defer func()`里面的`recover()`处理了这个`panic`,保证了整个程序能够执行完 2. 然后看f()函数返回的值为r,而不是n+1,这里考察的是函数的返回这一块的知识,所以最后的结果不是```return n+1```而是```n+1+n```的结果(第三点详细解释) 3. 为什么会等于7?看看最`f()`函数的最后一行为`return n+1`,也就是`return 3+1`,函数`f()`的返回参数为`r int`,所以`r = 3 + 1`,再到`defer func()`的`r+=n`也就是`r = n + 1 + n`即`r = 3 + 1 + 3`,然后返回r的值,就是7

👍

AntonyZhang
AntonyZhang · #26 · 3年之前

知识点是 panic、recover

QRQRQRqrqr
QRQRQRqrqr · #27 · 3年之前

defer panic

a406299736
a406299736 · #28 · 2年之前

1111

brothersam
brothersam · #29 · 2年之前

7,defer f()会恐慌。

wzbwzt
wzbwzt · #30 · 2年之前

1

feiyang
feiyang · #31 · 2年之前
huanfengnt
huanfengnt · #32 · 2年之前

f函数defer的时候还没有具体的内容

jatshw
jatshw · #33 · 2年之前

defer f() ,defer注册时候会panic ,3 + 4 = 7

flyZ
flyZ · #34 · 2年之前

mark

YuPeng
YuPeng · #35 · 2年之前

打卡

hasbug
hasbug · #36 · 2年之前

makr

Dessert
Dessert · #37 · 2年之前
577961141577961141 #12 回复

个人见解: 1. 考察了defer的调用,通过上面的```defer f()```可知,f()是没有定义的?(存疑)所以报了panic,而在`defer func()`里面的`recover()`处理了这个`panic`,保证了整个程序能够执行完 2. 然后看f()函数返回的值为r,而不是n+1,这里考察的是函数的返回这一块的知识,所以最后的结果不是```return n+1```而是```n+1+n```的结果(第三点详细解释) 3. 为什么会等于7?看看最`f()`函数的最后一行为`return n+1`,也就是`return 3+1`,函数`f()`的返回参数为`r int`,所以`r = 3 + 1`,再到`defer func()`的`r+=n`也就是`r = n + 1 + n`即`r = 3 + 1 + 3`,然后返回r的值,就是7

yep

huangyf168
huangyf168 · #38 · 2年之前

mark

feiyang
feiyang · #39 · 2年之前

defer f()会 panic: runtime error: invalid memory address or nil pointer dereference

oYto
oYto · #40 · 2年之前

这里在我的博客里进行了讲解,不懂的uu可以参考一下,若有不对的地方,欢迎指出 解释如下:

首先使用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

flyZ
flyZ · #41 · 2年之前

mark

hasbug
hasbug · #42 · 2年之前

mark

YuPeng
YuPeng · #43 · 2年之前

mark

jinxinli
jinxinli · #44 · 2年之前

mark

cllgeek
cllgeek · #45 · 2年之前

mark

amocea
amocea · #46 · 11月之前

声明的函数变量是 nil,所以 defer f() 的时候,会报 panic:nil pointer;所以会执行第一个 defer,第一个 defer 当中,r += n,即 r= 3;后面 recover(),执行 return;且 n + 1不是命名的返回值参数,所以 r += (n + 1),即为 7

Dessert
Dessert · #47 · 11月之前
liangmanlinliangmanlin #9 回复

6楼 @brunce ```golang // 先执行这一段代码, 然后 r 被赋值为 4 return n+1 // 然后执行,但是会触发panic defer f() // 最后执行,r 再加3 r=7,然后recover(),最后函数返回 7 defer func() { r += n recover() }() ```

mark

BigBigGopher
BigBigGopher · #48 · 11月之前

mark

Dessert
Dessert · #49 · 4月之前
liangmanlinliangmanlin #9 回复

6楼 @brunce ```golang // 先执行这一段代码, 然后 r 被赋值为 4 return n+1 // 然后执行,但是会触发panic defer f() // 最后执行,r 再加3 r=7,然后recover(),最后函数返回 7 defer func() { r += n recover() }() ```

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传