Golang 恢复

Golang 恢复

就像Java、C#等语言中的try/catch块是用来捕捉异常的,同样在Go语言中,recover函数也是用来处理恐慌的。它是一个内置的函数,定义在Go语言的内置包中。这个函数的主要用途是重新获得对恐慌的Goroutine的控制。或者换句话说,它可以处理Goroutine的慌乱行为。

语法

func recover() interface{}

重要的一点

  • 恢复函数总是在递延函数内调用,而不是在正常函数内调用。如果你在正常函数内或在递延函数外调用恢复函数,那么恢复函数不会停止恐慌序列,如例1所示。所以,总是在递延函数内调用recover函数,因为如果程序恐慌,递延函数不会停止执行,所以recover函数通过简单地恢复goroutine的正常执行来停止恐慌序列,并检索传递给panic调用的错误值,如例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

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程