Chapter 12 - Recovering from Failure
Exercise 1: defer
We need to be sure our Camp
function calls the Fire
value’s Extinguish
method before the program exits. But right now, Camp
is returning early due to an error, before Extinguish
can be called.
We don’t want to leave a lit Fire
unattended in the forest! Revise the Camp
function so that Extinguish
is always called, even if Camp
returns early.
Solution
package main
import "fmt"
type Fire struct {
lit bool
}
func (f Fire) Light() {
f.lit = true
fmt.Println("Fire lit:", f.lit)
}
func (f Fire) Extinguish() {
f.lit = false
fmt.Println("Fire lit:", f.lit)
}
func Camp() error {
var fire Fire
fire.Light()
// All you have to do is defer a call to Extinguish
// right after you make a call to Light! Extinguish
// will be called when Camp exits, whether Camp does
// so normally or due to an error.
defer fire.Extinguish()
return fmt.Errorf("spotted a bear")
fmt.Println("Toasting marshmallows")
return nil
}
func main() {
err := Camp()
if err != nil {
fmt.Println("Error:", err)
}
}
Output:
Fire lit: true
Fire lit: false
Error: spotted a bear