publish panic and defer

This commit is contained in:
Mark McGranaghan 2012-10-22 17:37:29 -04:00
parent c98e6b6504
commit e721314b97
5 changed files with 77 additions and 23 deletions

View File

@ -14,8 +14,6 @@ Multiple Return Values
Variadic Functions Variadic Functions
Closures Closures
Recursion Recursion
# Defer
# Panic
# Pointers # Pointers
# New # New
# Structs # Structs
@ -43,6 +41,9 @@ Mutexes
Stateful Goroutines Stateful Goroutines
Sorting Sorting
Sorting by Functions Sorting by Functions
Panic
Defer
# Recover
# Collection Functions # Collection Functions
# String Functions # String Functions
# String Formatting # String Formatting

View File

@ -1,18 +1,44 @@
// _Defer_ is used to ensure that a function call is
// performed later in a program's execution, usually for
// purposes of cleanup. `defer` is often used where e.g.
// `ensure` and `finally` would be used in other languages.
package main package main
import "fmt" import "fmt"
import "os"
func first() { // Suppose we wanted to create a file, write to it,
fmt.Println("1st") // and then close when we're done. Here's how we could
} // do that with `defer`.
func second() {
fmt.Println("2nd")
}
func main() { func main() {
defer second()
first() // Immediately after getting a file object with
// `createFile`, we defer the closing of that file
// with `closeFile`. This will be executed at the end
// of the enclosing function (`main`), after
// `writeFile` has finished.
f := createFile("/tmp/defer.txt")
defer closeFile(f)
writeFile(f)
} }
// todo: review http://blog.golang.org/2010/08/defer-panic-and-recover.html func createFile(p string) *os.File {
fmt.Println("creating")
f, err := os.Create(p)
if err != nil {
panic(err)
}
return f
}
func writeFile(f *os.File) {
fmt.Println("writing")
fmt.Fprintln(f, "data")
}
func closeFile(f *os.File) {
fmt.Println("closing")
f.Close()
}

6
examples/defer/defer.sh Normal file
View File

@ -0,0 +1,6 @@
# Running the program confirms that the file is closed
# after being written.
$ go run defer.go
creating
writing
closing

View File

@ -1,13 +1,25 @@
// A `panic` means something went unexpectedly wrong. // A `panic` typically means something went unexpectedly
// Mostly we use it to fail fast on errors that // wrong. Mostly we use it to fail fast on errors that
// shouldn't occur during normal operation. // shouldn't occur during normal operation, or that we
// aren't prepared to handle gracefully.
package main package main
import "os"
func main() { func main() {
// We'll use panic throught this book to check for // We'll use panic throughout this site to check for
// unexpected errors. This is the only program in the // unexpected errors. This is the only program on the
// book designed to panic. // site designed to panic.
panic("O noes") panic("a problem")
// A common use of panic is to abort if function
// returns an error value that we don't know how to
// (or want to) handle. Here's an example of
// `panic`king if we get an unexpected error when creating a new file.
f, err := os.Create("/tmp/file")
if err != nil {
panic(err)
}
} }

View File

@ -1,7 +1,16 @@
$ go run 26-panic.go # Running the program will cause it to panic, print
panic: O noes # an error message and goroutine traces, and exit with
# a non-zero status.
$ go run panic.go
panic: a problem
goroutine 1 [running]: goroutine 1 [running]:
main.main() main.main()
/.../src/26-panic.go:4 +0x47 /.../panic.go:12 +0x47
... ...
exit status 2
# Note that unlike some languages which use exceptions
# for handling of many errors, in Go it is idiomatic
# to use error-indicating return values wherever possible.
# We'll learn more about this in later examples.