Go语言教程之边写边学:panic和recover

在 Go中,panic 是一种机制,允许您在发生意外或不可恢复的情况时停止程序的正常执行。它类似于其他编程语言中的异常。触发紧急时,程序开始展开调用堆栈,运行与每个函数调用关联的任何延迟函数,然后崩溃并显示描述紧急原因的日志消息。

panic()函数的签名如下:

func panic(v interface{})

panic()函数采用空接口类型的单个参数v。这意味着您可以将任何类型的任何值作为参数传递给panic()。触发死机时,提供的值通常用于描述死机的原因,例如错误消息或错误对象。

 

使用panic()的示例

例如,假设您正在开发一个处理敏感信息的应用程序,并且它需要特定的配置文件才能正常工作。如果找不到文件或文件格式不正确,最好立即终止程序,而不是继续使用不正确或不完整的数据。

下面是一个不使用recover()的panic()示例:

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
)

type Config struct {
	SecretKey string `json:"secret_key"`
}

func main() {
	configData, err := ioutil.ReadFile("config.json")
	if err != nil {
		panic(fmt.Sprintf("Error reading configuration file: %v", err))
	}

	var config Config
	err = json.Unmarshal(configData, &config)
	if err != nil {
		panic(fmt.Sprintf("Error parsing configuration data: %v", err))
	}

	if config.SecretKey == "" {
		panic("Secret key is missing from configuration")
	}

	fmt.Println("Application started successfully.")
}

在此示例中,如果配置文件丢失、无法读取或 JSON 数据格式不正确,程序将死机并立即终止。这可确保应用程序不会继续使用无效的配置,这可能会导致数据泄漏或其他问题。

但是,这种类型的用法应保留用于严重错误,并且应始终尽可能努力优雅地处理错误。

panic: Error reading configuration file: open config.json: no such file or directory

goroutine 1 [running]:
main.main()
	/tmp/sandbox1728768757/prog.go:18 +0x179

 

使用recover()的示例

recover()是 Go 中的一个内置函数,用于重新控制一个panic的goroutine。当调用panic()时,程序的正常流程被中断,并且执行同一goroutine中的延迟函数。您可以在延迟函数中使用recover()来捕获 panic值、处理错误并防止程序崩溃。

recover()函数在延迟函数中调用时,返回传递给panic()的值。如果在延迟函数外部调用recover(),或者没有发生panic(),则返回nil。

recover() 函数的签名如下:

func recover() interface{}

recover()函数不接受任何参数,它返回一个interface{}类型的值,这是Go中的空接口。空接口可以保存任何类型的值,因此它允许recover()返回传递给panic()函数的任何值。

您可以修改给定的程序以使用recover()优雅地处理panic()。为此,您可以在main()函数中创建一个延迟函数,该函数将调用recover()并处理紧急情况。

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
)

type Config struct {
	SecretKey string `json:"secret_key"`
}

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Printf("An error occurred: %v\n", r)
			fmt.Println("Application terminated gracefully.")
		} else {
			fmt.Println("Application executed successfully.")
		}
	}()

	configData, err := ioutil.ReadFile("config.json")
	if err != nil {
		panic(fmt.Sprintf("Error reading configuration file: %v", err))
	}

	var config Config
	err = json.Unmarshal(configData, &config)
	if err != nil {
		panic(fmt.Sprintf("Error parsing configuration data: %v", err))
	}

	if config.SecretKey == "" {
		panic("Secret key is missing from configuration")
	}

	fmt.Println("Application started successfully.")
}

在这个修改后的程序中,我们添加了一个将调用recover()的延迟函数。如果出现紧急,延迟函数将捕获紧急值,打印错误消息,并正常终止应用程序。如果没有紧急情况,程序将继续执行,延迟函数在完成执行时将打印成功消息。

运行此代码将生成以下输出:

An error occurred: Error reading configuration file: open config.json: no such file or directory
Application terminated gracefully.
  • 当前日期:
  • 北京时间:
  • 时间戳:
  • 今年的第:18周
  • 我的 IP:18.190.176.26
农历
五行
冲煞
彭祖
方位
吉神
凶神
极简任务管理 help
+ 0 0 0
Task Idea Collect