MST

星途 面试题库

面试题:Go语言中defer的延迟执行时机陷阱

在Go语言中,假设我们有如下代码: ```go func main() { fmt.Println("start") defer fmt.Println("defer1") defer fmt.Println("defer2") fmt.Println("end") } ``` 请描述这段代码的输出顺序,并解释defer语句在这里延迟执行的具体机制。如果在`fmt.Println("end")`之前添加一个`return`语句,输出又会如何变化,为什么?
21.3万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 原代码输出顺序
    • 输出顺序为:
      start
      end
      defer2
      defer1
      
    • defer语句延迟执行机制
      • 当Go语言函数执行到defer语句时,并不会立即执行defer后的函数调用,而是将defer语句后的函数调用及其参数压入一个栈中。
      • 当包含defer语句的函数正常结束(例如遇到return语句、函数执行完毕等情况)时,会按照后进先出(LIFO,Last In First Out)的顺序依次执行defer栈中的函数调用。在这个例子中,defer fmt.Println("defer1")先执行,将其压入栈,然后defer fmt.Println("defer2")执行,也压入栈。当main函数执行完fmt.Println("end")后,函数正常结束,从defer栈中取出defer2对应的函数调用执行,再取出defer1对应的函数调用执行。
  2. 添加return语句后的输出变化
    • fmt.Println("end")之前添加return语句后,代码如下:
      func main() {
          fmt.Println("start")
          defer fmt.Println("defer1")
          defer fmt.Println("defer2")
          return
          fmt.Println("end")
      }
      
    • 输出顺序为:
      start
      defer2
      defer1
      
    • 原因
      • 当执行到return语句时,函数开始准备返回。此时,会先将defer栈中的函数按照后进先出的顺序执行,然后再返回。所以return语句并不会阻止defer语句的执行,而是在defer语句执行完毕后才真正返回。因此,fmt.Println("end")不会被执行,而defer语句后的fmt.Println("defer2")fmt.Println("defer1")会按照LIFO顺序执行。