面试题答案
一键面试异常(panic
)与错误(error
)处理方式的不同点
- 处理机制
- 异常(
panic
):panic
会立即停止当前函数的执行,并开始展开(unwind)调用栈,即依次调用调用栈中各个函数的延迟函数(defer
)。如果没有遇到recover
,程序最终会崩溃。 - 错误(
error
):error
类型是一种普通的返回值,函数调用者需要显式地检查返回的error
值,根据不同的错误情况进行相应处理,不会导致程序立即崩溃。
- 异常(
- 适用场景
- 异常(
panic
):适用于处理不可恢复的错误情况,例如程序内部逻辑错误、资源严重不足等,这些情况一旦发生,程序继续运行可能会导致更严重的问题。 - 错误(
error
):适用于处理预期内可能发生的错误,例如文件读取失败、网络请求失败等,程序可以通过合理的处理继续运行。
- 异常(
- 传播方式
- 异常(
panic
):panic
会沿着调用栈向上传播,直到被recover
捕获或者程序终止。 - 错误(
error
):error
通过函数的返回值来传递,调用者负责检查和处理错误,调用者可以选择继续传递错误给上层调用者,也可以自行处理。
- 异常(
异常(panic
)处理示例
package main
import (
"fmt"
)
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
panic("This is a panic")
fmt.Println("This line will not be printed")
}
在这个示例中,panic
被触发后,程序开始展开调用栈,defer
函数中的 recover
捕获到 panic
,并输出相应信息,程序不会崩溃。
错误(error
)处理示例
package main
import (
"fmt"
)
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Result:", result)
}
在这个示例中,divide
函数返回一个 error
值,调用者通过检查 err
是否为 nil
来判断是否发生错误,并进行相应处理,程序可以继续执行。