Comment on page

19 延迟调用(Defer)

在一个复杂函数中,很容易忘记释放资源(例如,关闭文件句柄或释放互斥锁)。
您可以使用defer语句,将释放资源的代码放在获取资源的代码的附近:
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总会被调用。这对具有多个出口点的大型函数尤其有用。
如果需要延迟调用的代码比较复杂,您可以使用函数字面量:
func foo() {
mutex1.Lock()
mutex2.Lock()
defer func() {
mutex2.Unlock()
mutex1.Unlock()
}()
// ... more code
}
您也可以使用多个defer语句,它们会被逆序调用,例如第一个声明的defer语句会在最后执行。
即便发生了panic,延迟函数也会被调用。