In Go, you can defer a function call. That means you make a call
expression, but it is not run until after the calling function
exits. It's intended for cleanup purposes.
One very important point is that a deferred function will be run even
if the function that started it panics (crashes). That assures that
the final cleanup will occur even when things go wrong.
Also notice that when the function demo panics, the
deferred function is run, and after it the deferred function from main
is run, even though the rest of the main function itself is not run.
There are defer statements in main and in
demo. Notice that the one in demo uses a function which
is created and named, then used in the defer. The one in main
combines the creation and the call. Instead of following the function
name with (), the definition is followed by (), which runs
the function which is never named.
package main
import "fmt"
/*
* The defer function.
*/
func demo() {
// Keep count and total of entered numbers.
tot := 0
count := 0
// Cleanup to give the final stats.
finisher := func() {
fmt.Printf("=== You entered %d numbers, average %g ===\n",
count, float32(tot)/float32(count))
}
defer finisher()
// Words for input numbers.
words := [20]string {
"zip", "wumpus", "goobers", "thump", "ding!",
"teeth", "snorkel", "airplane", "warble", "snack",
"northern", "morph", "angle", "tongs", "conduit",
"island", "sunrise", "orbit", "dice", "meatball" }
// 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
}
// Print the number and its word.
fmt.Printf("You entered %d: %s\n", val, words[val])
// Count and total.
count++
tot += val
}
}
func main() {
// This function runs essentially after main finishes. The
// systax here both creates a function and calls it, never giving
// it a name.
defer func() { fmt.Println("And now we are past done.") } ()
demo()
fmt.Println("Now the main program is done")
}