例如,下面的代码中,如果输入的数字是 0,那么程序会触发 panic,并打印出错误信息。但是由于在 main 函数中使用了 defer 和 recover,所以程序不会崩溃,而是继续执行后面的语句。
package main
import "fmt"
func divide(a, b int) int {
if b == 0 {
panic("division by zero")
}
return a / b
}
func main() {
defer func() {
if err := recover(); err != nil {
fmt.Println("Recovered from", err)
}
}()
fmt.Println(divide(10, 2))
fmt.Println(divide(10, 0))
fmt.Println("This statement will not run")
}
例如,下面的代码中,在 foo 函数中调用了 panic,并传入了一个字符串作为参数。这个字符串会被打印出来,并且 foo 函数和 main 函数都会被终止。
package main
import "fmt"
func foo() {
fmt.Println("Before panic")
panic("Something went wrong")
fmt.Println("After panic") // This statement will not run
}
func main() {
fmt.Println("Calling foo")
foo()
fmt.Println("Returned from foo") // This statement will not run
}
例如,下面的代码中,在 bar 函数中使用了 defer 和 recover 来捕获到 foo 函数触发的 panic,并打印出相应的信息。这样就避免了整个程序被终止。
package main
import "fmt"
func foo() {
fmt.Println("Before panic")
panic(42) // You can use any type as the argument of panic
}
func bar() {
defer func() {
if x := recover(); x != nil { // You can assign the return value of recover to a variable
fmt.Printf("Recovered from %v\n", x)
}
}()
fmt.Println("Calling foo")
foo()
}
func main() {
bar()
fmt.Println("Returned from bar") // This statement will still run
}