822 words
4 minutes
Go语言教程:深入理解defer、panic和recover
在Go语言中,defer、panic和recover是三个非常重要的关键字,它们在处理错误和资源管理方面起着至关重要的作用。本文将通过几个示例代码,深入浅出地讲解这三个关键字的用法和注意事项。
示例1:defer的基本用法
package main
import "fmt"
func main() {
defer fmt.Println("first defer")
for i := 0; i < 3; i++ {
defer fmt.Printf("defer in for [%d]\\n", i)
}
defer fmt.Println("last defer")
}
解析
- defer的执行顺序:
defer语句会将其后的函数调用推迟到包含它的函数即将返回的时候执行。- 多个
defer语句的执行顺序是后进先出(LIFO)。
- 代码执行顺序:
main函数开始执行,首先注册defer fmt.Println("first defer")。- 进入
for循环,依次注册defer fmt.Printf("defer in for [%d]\\n", i),其中i的值分别为0、1、2。 - 注册
defer fmt.Println("last defer")。 main函数即将返回时,按照后进先出的顺序执行所有的defer语句。
输出结果
last defer
defer in for [2]
defer in for [1]
defer in for [0]
first defer
示例2:panic和recover的用法
package main
import (
"errors"
"fmt"
)
func main() {
fmt.Println("Enter function main.")
defer func() {
fmt.Println("Enter defer function.")
// recover函数的正确用法。
if p := recover(); p != nil {
fmt.Printf("panic: %s\\n", p)
}
fmt.Println("Exit defer function.")
}()
// recover函数的错误用法。
fmt.Printf("no panic: %v\\n", recover())
// 引发panic。
panic(errors.New("something wrong"))
// recover函数的错误用法。
p := recover()
fmt.Printf("panic: %s\\n", p)
fmt.Println("Exit function main.")
}
解析
- panic:
panic用于引发一个恐慌,终止当前函数的执行,并开始沿着调用栈向上回溯,直到遇到recover或程序崩溃。
- recover:
recover用于终止panic的回溯,恢复正常的执行流程。它只能在defer函数中有效。
- 代码执行顺序:
main函数开始执行,打印"Enter function main."。- 注册
defer函数。 - 调用
recover(),此时没有panic,返回nil。 - 引发
panic,错误信息为"something wrong"。 defer函数被调用,recover捕获到panic,打印错误信息。defer函数执行完毕,main函数继续执行。
输出结果
Enter function main.
no panic: <nil>
Enter defer function.
panic: something wrong
Exit defer function.
示例3:panic的正确和错误用法
package main
import (
"errors"
"fmt"
)
func main() {
fmt.Println("Enter function main.")
caller()
fmt.Println("Exit function main.")
}
func caller() {
fmt.Println("Enter function caller.")
panic(errors.New("something wrong")) // 正例。
panic(fmt.Println) // 反例。
fmt.Println("Exit function caller.")
}
解析
- panic的正确用法:
panic(errors.New("something wrong")):引发一个带有错误信息的panic。
- panic的错误用法:
panic(fmt.Println):fmt.Println是一个函数,不是错误信息或字符串,使用不当。
- 代码执行顺序:
main函数开始执行,打印"Enter function main."。- 调用
caller函数。 caller函数引发panic,错误信息为"something wrong",程序终止。
输出结果
Enter function main.
Enter function caller.
panic: something wrong
总结
通过以上示例,我们可以总结出以下几点:
- defer:
- 用于延迟函数的执行,直到包含它的函数即将返回时执行。
- 多个
defer语句按照后进先出的顺序执行。
- panic:
- 用于引发一个恐慌,终止当前函数的执行,并开始沿着调用栈向上回溯。
- recover:
- 用于终止
panic的回溯,恢复正常的执行流程。只能在defer函数中有效。
- 用于终止
通过理解和掌握defer、panic和recover的用法,可以更好地处理Go语言中的错误和资源管理,提高代码的健壮性和可维护性。
Go语言教程:深入理解defer、panic和recover
https://blog.ithuo.net/posts/go-language-defer-panic-recover/