延迟函数调用
Go有一个名为defer的特殊语句,它计划在函数完成后运行函数调用。请考虑以下示例:
package main
import "fmt"
func first() {
fmt.Println("First")
}
func second() {
fmt.Println("Second")
}
func main() {
defer second()
first()
}
此程序打印“first”,然后打印“second”。
defer 语句通常与配对操作(如打开和关闭、连接和断开连接或锁定和解锁)一起使用,以确保在所有情况下释放资源,无论控制流多么复杂。释放资源的defer语句的正确位置是在成功获取资源后立即进行。
下面是打开文件并对其执行读/写操作的示例。在此示例中,通常有一些地方您希望提前返回。
没有延迟
func ReadWrite() bool {
file.Open("file")
if failureX {
file.Close()
return false
}
if failureY {
file.Close()
return false
}
file.Close()
return true
}
这里重复了很多代码。为了克服这一点,Go有延迟语句。上面的代码可以重写如下。这使得函数更具可读性,更短,并将关闭放在打开旁边。
延迟调用
func ReadWrite() bool {
file.Open("file")
defer file.Close()
if failureX {
return false
}
if failureY {
return false
}
return true
}
这具有多种优点:
- 它将我们的关闭呼叫保持在打开呼叫附近,因此更容易理解。
- 如果我们的函数有多个返回语句(可能一个在if中,一个在另一个中),则Close将发生在它们之前。
- 即使发生运行时崩溃,也会运行延迟函数。
- 延迟函数按LIFO顺序执行,因此上面的代码打印:4 3 2 1 0。
- 您可以将多个函数放在“延迟列表”上,就像这个例子一样。
package main
import "fmt"
func main() {
for i := 0; i < 5; i++ {
defer fmt.Printf("%d ", i)
}
}