面试题答案
一键面试- 预测输出结果及解释:
- 输出结果为:
defer2 defer1 some error result: 3
- defer执行顺序:在Go语言中,defer语句会在函数返回前按后进先出(LIFO)的顺序执行。这里先定义了两个defer语句,所以
defer func() { num = num + 2; fmt.Println("defer2") }()
会在defer func() { num++ ; fmt.Println("defer1") }()
之前执行。 - 对返回值的影响:Go语言的函数返回值在执行到
return
语句时会创建一个返回值的副本(如果有命名返回值,会先将命名返回值赋值给副本)。这里num
是命名返回值,在执行return num, err
时,num
的值0被复制到返回值副本中。然后defer语句按顺序执行,先执行num = num + 2
,num
变为2,再执行num++
,num
变为3。但返回值副本在return
语句执行时已确定,所以最终返回的num
值是0,经过defer修改后的num
值3不会影响最初确定的返回值副本。不过在main
函数中打印result
时,它获取的是命名返回值num
最终的值3(因为命名返回值在函数结束时保存了最后修改的值),而错误err
则正常返回并被main
函数捕获打印。
- 输出结果为:
- 假设拆分
return
的输出结果及原因:- 假设可拆分为
return num
和return err
,输出结果为:defer2 defer1 some error result: 1
- 原因:当执行
return num
时,num
值为0,按defer的LIFO顺序,先执行defer func() { num = num + 2; fmt.Println("defer2") }()
,num
变为2,再执行defer func() { num++ ; fmt.Println("defer1") }()
,num
变为3。但此时函数已返回num
值0,num
后续的修改不会影响已返回的值。当执行return err
时,只是返回错误,不会影响result
的值。而在main
函数中打印result
时,由于return num
已返回0,后续num
的修改不影响result
,所以result
为0经过第一个defer
语句修改后的1(因为第一个defer
先执行num = num + 2
,但返回值已确定为0,第二个defer
num++
对返回值无影响,而在main
函数获取命名返回值num
时,它经过了第一个defer
的修改)。
- 假设可拆分为