MST

星途 面试题库

面试题:Go中defer和recover在复杂函数结构中的应用

假设有一个多层嵌套调用的Go函数结构,最外层函数调用中层函数,中层函数再调用内层函数。在内层函数可能会因为某些条件触发panic。请设计代码,通过defer和recover机制,在最外层函数捕获并处理内层函数的panic,同时确保中层函数在出现panic时能正确清理相关资源(例如关闭文件描述符)。说明代码逻辑以及defer和recover在其中的作用。
38.9万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "fmt"
)

// 模拟内层函数,可能触发 panic
func innerFunction() {
    panic("Inner function panic")
}

// 中层函数,调用内层函数,并负责清理资源
func middleFunction() {
    // 模拟打开文件描述符
    fmt.Println("Middle function: Opening file descriptor")
    defer func() {
        // 模拟关闭文件描述符
        fmt.Println("Middle function: Closing file descriptor")
    }()
    innerFunction()
}

// 最外层函数,捕获并处理内层函数的 panic
func outerFunction() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Printf("Outer function caught panic: %v\n", r)
        }
    }()
    middleFunction()
}

代码逻辑

  1. innerFunction:这是最内层函数,它简单地触发一个 panic
  2. middleFunction:此函数调用 innerFunction。同时,它通过 defer 语句注册了一个匿名函数,用于在函数结束时清理资源(这里简单地打印关闭文件描述符的信息)。无论 innerFunction 是否触发 panic,这个 defer 函数都会在 middleFunction 结束时执行。
  3. outerFunction:这是最外层函数,它调用 middleFunction。通过 defer 语句注册了一个匿名函数,在这个匿名函数中使用 recover 来捕获可能来自内层函数的 panic。如果捕获到 panic,则打印出相关信息。

deferrecover 的作用

  1. defer
    • middleFunction 中,defer 用于注册资源清理函数。无论函数是正常结束还是因为 panic 而结束,defer 注册的函数都会被执行,确保资源(如文件描述符)被正确清理。
    • outerFunction 中,defer 用于注册一个匿名函数,这个匿名函数用于捕获 panicdefer 的特性保证了这个捕获逻辑在函数即将结束时执行,无论函数是正常结束还是因为 panic 而结束。
  2. recover
    • outerFunctiondefer 匿名函数中,recover 用于捕获 panic。当内层函数触发 panic 时,recover 可以使程序从 panic 状态中恢复,避免程序崩溃,并允许外层函数对 panic 进行处理。
func main() {
    outerFunction()
    fmt.Println("Program continues after handling panic")
}

main 函数中调用 outerFunction,可以看到程序在捕获并处理 panic 后继续执行。