延迟函数调用

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)
	}
}