MST
星途 面试题库

面试题:Go defer在复杂函数调用栈中的行为及资源释放

假设有一个函数A,在函数A中调用函数B,函数B中又调用函数C,且每个函数中都有defer语句。当函数C出现错误返回时,描述defer语句的执行流程以及如何确保所有相关资源都能正确释放。请通过代码示例进行解释。
15.1万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. defer语句执行流程
    • 在Go语言中,defer语句会在函数即将返回时执行。当函数C出现错误返回时,会先执行函数C中的defer语句,然后回到函数B,执行函数B中的defer语句,最后回到函数A,执行函数A中的defer语句。这是因为defer语句是按照后进先出(LIFO)的顺序执行的。
  2. 确保资源正确释放的方法
    • 每个函数中的defer语句用于释放该函数中申请的资源。只要在每个函数中合理使用defer语句来关闭文件、断开数据库连接等资源相关操作,就能确保所有相关资源在函数返回时都能正确释放。
  3. 代码示例
package main

import (
    "fmt"
)

func C() error {
    fmt.Println("Enter C")
    defer func() {
        fmt.Println("Defer in C")
    }()
    return fmt.Errorf("error in C")
}

func B() error {
    fmt.Println("Enter B")
    defer func() {
        fmt.Println("Defer in B")
    }()
    return C()
}

func A() error {
    fmt.Println("Enter A")
    defer func() {
        fmt.Println("Defer in A")
    }()
    return B()
}

func main() {
    err := A()
    if err!= nil {
        fmt.Println("Error:", err)
    }
}

在上述代码中:

  • A调用BB调用C时,C出现错误返回。
  • 首先输出Enter C,然后因为C返回错误,执行C中的defer语句,输出Defer in C
  • 回到B,执行B中的defer语句,输出Defer in B
  • 回到A,执行A中的defer语句,输出Defer in A
  • 最后在main函数中打印出Error: error in C。这样就保证了每个函数中defer语句按照LIFO顺序执行,确保资源正确释放。