MST

星途 面试题库

面试题:Go中panic和recover与defer的配合使用

在Go语言中,defer、panic和recover经常会一起配合使用。请详细阐述它们之间的执行顺序,并编写一个复杂点的示例代码,展示在多层嵌套函数调用中,如何通过defer和recover来优雅地处理panic,确保程序的稳定性。
10.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 执行顺序阐述

    • defer语句会将其后面的函数调用延迟到包含该defer语句的函数即将返回时执行。多个defer语句会按照后进先出(LIFO)的顺序执行。
    • panic用于抛出一个运行时错误,当panic发生时,当前函数会立即停止执行,其所有的defer语句会按照LIFO顺序执行。然后,panic会向上传递到调用栈的上一层函数,重复这个过程,直到程序崩溃或者被recover捕获。
    • recover只能在defer函数中使用,用于捕获panic。当recover被调用时,如果当前的goroutine正处于panic状态,它会捕获panic的值并停止panic的传播,使程序可以继续正常执行。
  2. 示例代码

package main

import (
    "fmt"
)

func innerMost() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("InnerMost recovered:", r)
        }
    }()
    panic("InnerMost panic")
}

func middle() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Middle recovered:", r)
        }
    }()
    innerMost()
}

func outer() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Outer recovered:", r)
        }
    }()
    middle()
}

func main() {
    outer()
    fmt.Println("Program continues after panic handling")
}

在这个示例中:

  • innerMost函数引发了一个panic
  • 由于innerMost函数中有defer语句,在panic发生时,defer函数会执行,尝试捕获panic
  • 如果innerMost函数没有捕获panicpanic会传播到middle函数,middle函数的defer语句会执行,尝试捕获panic
  • 同理,如果middle函数没有捕获panicpanic会传播到outer函数,outer函数的defer语句会执行,尝试捕获panic
  • 无论哪个函数捕获了panic,程序都不会崩溃,并且main函数中的后续代码可以继续执行。