Recover

This example is similar to the last one, but shows some additional features.

A deferred function can call the builtin function recover. This ends the panic. After the deferred function finishes, control returns to the caller of the function that panicked (and which called the deferred function before it panicked). The emergency is over, and the program continues to run normally from that point.

Recover returns an error object, which can be pretty much any type. The function returns nil if there is not a panic, or if its caller is not running as a deferred function call.

This example also shows a call the the built-in panic function. This simply causes a panic, and can take an argument of pretty much any type. This is the value delivered to recover function if called.

package main import "fmt" /* * Using recover in the defer function. This is a just variation on the * the last example. */ func demo() { // Keep count and total of entered numbers. tot := 0 count := 0 // Cleanup to give the final stats. defer func() { err := recover() if err != nil { // The %v conversion is "the value in a default format" // That is, just make it work. fmt.Printf("Ooops! %v\n", err) } fmt.Printf("=== You entered %d numbers, average %g ===\n", count, float32(tot)/float32(count)) } () // Words for input numbers. words := [20]string { "water", "land", "air", "sea", "horizon", "skyline", "landscape", "wind", "snow", "rain", "sunset", "sunrise", "eclipse", "nightime", "moonshine", "mountain", "plane", "valley", "lake", "firth" } // Read numbers and print them, with their words. for { // Read a number. var val int fmt.Print("Pls enter a number: ") rdct, _ := fmt.Scan(&val) if rdct == 0 { break } // Special handling. if val == 42 { panic("Failed to ask for the question") } // Print the number and its word. fmt.Printf("You entered %d: %s\n", val, words[val]) // Count and total. count++ tot += val } } func main() { demo() fmt.Println("And now we are done.") }