就像Java、C# 等语言中异常中的 try/catch 块在 Go 语言中类似用于捕获异常一样,recover函数用于处理恐慌。它是一个内置函数,定义在 Go 语言的 builtin 包下。这个函数的主要用途是重新获得对恐慌 Goroutine 的控制。或者换句话说,它处理 Goroutine 的恐慌行为。
句法:
func recover() interface{}
要点:
- 恢复函数总是在延迟函数内部函数,而不是在普通函数。如果调用恢复正常函数的延迟函数内部或外部函数,那么恢复函数不会停止序列恐慌中所示例1所以,一直呼吁恢复延迟函数内部函数,因为延迟函数不停止执行如果程序崩溃,那么recover函数通过简单地恢复goroutine的正常执行并检索传递给panic调用的错误值来停止panicking序列,如示例2所示。
- 仅当您调用发生恐慌的同一个 goroutine 时,恢复函数才起作用。如果您在不同的 goroutine 中调用它,那么它将无法如示例 3 所示那样工作。
- 如果要查找堆栈跟踪,请使用 Debug 包下定义的 PrintStack函数。
示例 1:
// Go program which illustrates
// the concept of recover
package main
import "fmt"
// This function is created to handle
// the panic occurs in entry function
// but it does not handle the panic
// occurred in the entry function
// because it called in the normal
// function
func handlepanic() {
if a := recover(); a != nil {
fmt.Println("RECOVER", a)
}
}
// Function
func entry(lang *string, aname *string) {
// Normal function
handlepanic()
// When the value of lang
// is nil it will panic
if lang == nil {
panic("Error: Language cannot be nil")
}
// When the value of aname
// is nil it will panic
if aname == nil {
panic("Error: Author name cannot be nil")
}
fmt.Printf("Author Language: %s \n Author Name: %s\n", *lang, *aname)
fmt.Printf("Return successfully from the entry function")
}
// Main function
func main() {
A_lang := "GO Language"
entry(&A_lang, nil)
fmt.Printf("Return successfully from the main function")
}
输出:
panic: Error: Author name cannot be nil
goroutine 1 [running]:
main.entry(0x41a788, 0x0)
/tmp/sandbox777592252/prog.go:35 +0x180
main.main()
/tmp/sandbox777592252/prog.go:46 +0x40
示例 2:
// Go program which illustrates
// the concept of recover
package main
import (
"fmt"
)
// This function handles the panic
// occur in entry function
// with the help of the recover function
func handlepanic() {
if a := recover(); a != nil {
fmt.Println("RECOVER", a)
}
}
// Function
func entry(lang *string, aname *string) {
// Deferred function
defer handlepanic()
// When the value of lang
// is nil it will panic
if lang == nil {
panic("Error: Language cannot be nil")
}
// When the value of aname
// is nil it will panic
if aname == nil {
panic("Error: Author name cannot be nil")
}
fmt.Printf("Author Language: %s \n Author Name: %s\n", *lang, *aname)
fmt.Printf("Return successfully from the entry function")
}
// Main function
func main() {
A_lang := "GO Language"
entry(&A_lang, nil)
fmt.Printf("Return successfully from the main function")
}
输出:
RECOVER Error: Author name cannot be nil
Return successfully from the main function
示例 3:
// Go program which illustrates
// recover in a goroutine
package main
import (
"fmt"
"time"
)
// For recovery
func handlepanic() {
if a := recover(); a != nil {
fmt.Println("RECOVER", a)
}
}
/* Here, this panic is not
handled by the recover
function because of the
recover function is not
called in the same
goroutine in which the
panic occurs */
// Function 1
func myfun1() {
defer handlepanic()
fmt.Println("Welcome to Function 1")
go myfun2()
time.Sleep(10 * time.Second)
}
// Function 2
func myfun2() {
fmt.Println("Welcome to Function 2")
panic("Panicked!!")
}
// Main function
func main() {
myfun1()
fmt.Println("Return successfully from the main function")
}
输出:
Welcome to Function 1
Welcome to Function 2
panic: Panicked!!
goroutine 6 [running]:
main.myfun2()
/tmp/sandbox157568972/prog.go:31 +0xa0
created by main.myfun1
/tmp/sandbox157568972/prog.go:24 +0xc0