822 words
4 minutes

Go语言教程:深入理解defer、panic和recover

在Go语言中,deferpanicrecover是三个非常重要的关键字,它们在处理错误和资源管理方面起着至关重要的作用。本文将通过几个示例代码,深入浅出地讲解这三个关键字的用法和注意事项。

示例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")
}

解析#

  1. defer的执行顺序
    • defer语句会将其后的函数调用推迟到包含它的函数即将返回的时候执行。
    • 多个defer语句的执行顺序是后进先出(LIFO)。
  2. 代码执行顺序
    • 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.")
}

解析#

  1. panic
    • panic用于引发一个恐慌,终止当前函数的执行,并开始沿着调用栈向上回溯,直到遇到recover或程序崩溃。
  2. recover
    • recover用于终止panic的回溯,恢复正常的执行流程。它只能在defer函数中有效。
  3. 代码执行顺序
    • 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.")
}

解析#

  1. panic的正确用法
    • panic(errors.New("something wrong")):引发一个带有错误信息的panic
  2. panic的错误用法
    • panic(fmt.Println)fmt.Println是一个函数,不是错误信息或字符串,使用不当。
  3. 代码执行顺序
    • main函数开始执行,打印"Enter function main."
    • 调用caller函数。
    • caller函数引发panic,错误信息为"something wrong",程序终止。

输出结果#

Enter function main.
Enter function caller.
panic: something wrong

总结#

通过以上示例,我们可以总结出以下几点:

  1. defer
    • 用于延迟函数的执行,直到包含它的函数即将返回时执行。
    • 多个defer语句按照后进先出的顺序执行。
  2. panic
    • 用于引发一个恐慌,终止当前函数的执行,并开始沿着调用栈向上回溯。
  3. recover
    • 用于终止panic的回溯,恢复正常的执行流程。只能在defer函数中有效。

通过理解和掌握deferpanicrecover的用法,可以更好地处理Go语言中的错误和资源管理,提高代码的健壮性和可维护性。

Share

If this article helped you, please share it with others!

Go语言教程:深入理解defer、panic和recover
https://blog.ithuo.net/posts/go-language-defer-panic-recover/
Author
Derick
Published at
2022-05-19
License
CC BY-NC-SA 4.0
Last updated on 2022-05-19,1350 days ago

Some content may be outdated

Table of Contents