阐述一下Go的defer原理 ?
在Go语言中,defer
关键字用于在函数返回前执行一段代码或调用一个清理函数。这对于处理像文件关闭、解锁或者返回一些资源到资源池等操作非常有用。
当你在一个函数内部调用defer
关键字,Go实际上会把它后面的函数(通常是一个匿名函数或清理函数)压入一个栈中。当外部函数准备返回时,Go会按照后进先出(LIFO)的顺序调用并执行这个栈中的所有函数。
需要注意的是,defer
语句的参数会在defer
语句处就计算好,而不是在外部函数返回时才计算。这意味着下面的代码会首先打印出0
:
func main() {
i := 0
defer fmt.Println(i)
i++
return
}
defer
的使用可以简化一些代码的复杂度,比如在异常处理和资源清理等场景。例如,当打开一个文件进行操作后,可以立即调用defer
来确保文件最后被关闭:
func main() {
file, err := os.Open("file.go")
if err != nil {
// handle the error here
return
}
defer file.Close()
// continue to work with file
}
在这个例子中,不论后续的代码路径如何,file.Close()
总会在main()
函数结束之前被调用到,这样就确保了资源的正确释放。