面试题答案
一键面试- 原代码输出结果及原因:
- 输出结果:5 4 3 2 1
- 原因:在Go语言中,
defer
语句会将其后面跟随的函数延迟到包含该defer
语句的函数结束时执行。这些被延迟执行的函数会以栈的方式进行存储,后进先出(LIFO)。在for
循环中,每次迭代都会将fmt.Println(i)
函数压入defer
栈,当for
循环结束时,main
函数也即将结束,此时会从defer
栈中依次弹出函数并执行,由于是栈结构,最后压入的fmt.Println(5)
最先执行,以此类推,所以输出顺序是5 4 3 2 1。
- 修改代码以按1到5顺序输出:
package main
import "fmt"
func main() {
var stack []int
for i := 1; i <= 5; i++ {
stack = append(stack, i)
}
for len(stack) > 0 {
index := len(stack) - 1
defer fmt.Println(stack[index])
stack = stack[:index]
}
}
这里先将数字1到5存入切片stack
,然后通过defer
结合从切片栈顶弹出元素的方式,保证defer
执行时按1到5的顺序输出。另一种方式是使用匿名函数结合闭包:
package main
import "fmt"
func main() {
for i := 1; i <= 5; i++ {
j := i
defer func() {
fmt.Println(j)
}()
}
}
这里通过创建局部变量j
,将每次循环的i
值捕获到闭包中,避免了defer
执行时i
已经是循环结束后的最终值的问题,从而按1到5顺序输出。