正常的函数调用是这样的:
package main
import (
"log"
)
func main() {
log.Print("1");
log.Print("2");
log.Print("3");
}
屏幕输出:
2021/06/17 10:51:29 1
2021/06/17 10:51:29 2
2021/06/17 10:51:29 3
被延迟的函数调用时这样的:
package main
import (
"log"
)
func main() {
defer log.Print("1"); // delay exection at end of main(), first in last out
defer log.Print("2"); // delay exection at end of main(), first in last out
log.Print("3");
}
屏幕输出:
2021/06/17 10:56:04 3
2021/06/17 10:56:04 2
2021/06/17 10:56:04 1
所以defer
是写在函数调用前面,使得当前函数的执行延迟到上一级函数退出的时候。
关于defer
,记住两点就够了:
-
defer
使函数调用入堆栈,当上一级函数退出时执行。多个defer
按照堆栈规则,先入后出。 -
defer
的函数入参立即生效,例如:
package main
import (
"log"
)
func main() {
i := 0
defer log.Print(i)
i++
}
输出时0,而不是1。因为defer的函数入参是立即取值的。
````defer```最经典的应用是释放资源,例如:
package main
import (
"os"
)
func main() {
f, _ := os.Create("test.txt")
defer f.Close()
f.WriteString("Hello World!")
/* defer f.Close() will be executed here */
}
有了defer的好处是,申请和释放资源的代码可以非常非常的近。
参考
https://www.geeksforgeeks.org/defer-keyword-in-golang/
https://www.digitalocean.com/community/tutorials/understanding-defer-in-go
https://dev.to/luciferchase/what-the-heck-is-defer-in-golang-35imko