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.")
}