# 19 延迟调用(Defer)

在一个复杂函数中，很容易忘记释放资源（例如，关闭文件句柄或释放互斥锁）。

您可以使用`defer`语句，将释放资源的代码放在获取资源的代码的附近：

```go
func foo() {
  f, err := os.Open("myfile.txt")
  if err != nil {
    return
  }
  defer f.Close()

  // ... lots of code
}
```

上述例子中，`defer f.Close()`确保了`f.Close()`会在`foo`退出之前被调用。

把`defer f.Close()`紧跟着`os.Open()`放置，使得代码审查变得轻松，可核实`Close`总会被调用。这对具有多个出口点的大型函数尤其有用。

如果需要延迟调用的代码比较复杂，您可以使用函数字面量：

```go
func foo() {
  mutex1.Lock()
  mutex2.Lock()

  defer func() {
    mutex2.Unlock()
    mutex1.Unlock()
  }()

  // ... more code
}
```

您也可以使用多个`defer`语句，它们会被逆序调用，例如第一个声明的`defer`语句会在最后执行。

即便发生了`panic`，延迟函数也会被调用。
