Deferred Functions

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