defer
- defer 语句中的函数会在 return 语句更新返回值变量后再执行
for _, filename := range filenames {
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close() // NOTE: risky; could run out of file
descriptors
// ...process f…
}
上边的示例会在整个函数结束后执行,可能会导致文件描述符耗尽,这种情况可以通过封装函数或者闭包改进
for _, filename := range filenames {
if err := doFile(filename); err != nil {
return err
}
}
func doFile(filename string) error {
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close()
// ...process f…
}
- 可以在一个函数中执行多条 defer 语句,它们的执行顺序与声明顺序相反
package main
import (
"fmt"
)
func main() {
defer func() {
fmt.Println("defer 1")
}()
defer func() {
fmt.Println("defer 2")
}()
fmt.Println("main finish")
}
输出
main finish
defer 2
defer 1
- 被延迟执行的匿名函数甚至可以修改函数返回给调用者的返回值
func triple(x int) (result int) {
defer func() { result += x }()
return double(x)
}
fmt.Println(triple(4)) // "12"