Godefer教程展示了如何在Golang中使用defer语句延迟执行。
defer语句推迟函数的执行,直到周围的函数返回。立即评估延迟调用的参数。
defer语句将defer关键字之后的函数调用添加到堆栈中。由于调用放在堆栈上,因此称为后进先出(LIFO)顺序。
defer语句的一个常见用途是清理资源,例如打开的文件、网络连接或数据库句柄。
$ go version go version go1.18.1 linux/amd64
我们使用Go版本1.18。
去延迟语句
下面是Go的defer语句的简单演示。
package main
import "fmt"
func main() {
defer fmt.Println("sky")
fmt.Println("falcon")
}
我们有两个Println函数调用。第一个用defer关键字延迟。
$ go run simple.go falcon sky
去延迟参数评估
延迟函数的参数会立即求值。
package main
import "fmt"
func main() {
fmt.Println("start")
for i := 1; i <= 5; i++ {
defer fmt.Println(i)
}
fmt.Println("end")
}
defer语句放在for循环内。i变量在循环执行期间被评估。
$ go run arg_eval.go start end 5 4 3 2 1
去延迟函数调用顺序
延迟的函数调用放在堆栈上,并以后进先出(LIFO)的顺序调用。
package main
import "fmt"
func main() {
defer fmt.Println("one")
defer fmt.Println("two")
defer fmt.Println("three")
defer fmt.Println("four")
defer fmt.Println("4")
defer fmt.Println("3")
defer fmt.Println("2")
defer fmt.Println("1")
}
deferfmt.Println("one")先延迟,最后执行。deferfmt.Println("1")最后延迟并首先执行。
$ go run defer_order.go 1 2 3 4 four three two one
去延迟资源释放
defer语句常用于释放必要的资源,如打开的文件。
sky cloud cup wood rock sea tree oil book falcon
这是words.txt文件。
package main
import (
"bufio"
"fmt"
"log"
"os"
)
func main() {
f, err := os.Open("words.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
}
在代码示例中,我们逐行读取打开的文件。
f, err := os.Open("words.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
打开words.txt文件并检查错误后,我们延迟Close方法。它在main函数结束时释放打开的文件。
恐慌地推迟
延迟的函数调用即使在函数崩溃时也会执行。
package main
import "fmt"
func main() {
defer fmt.Println("sky")
panic("terminating")
fmt.Println("falcon")
}
该示例在延迟Println函数后调用panic;尽管如此,它还是被执行了。
$ go run defpanic.go sky panic: terminating goroutine 1 [running]: main.main() /home/janbodnar/Documents/prog/golang/defer/defpanic/defpanic.go:7 +0xb9 exit status 2
在本教程中,我们介绍了Golang中的defer语句。
列出所有Go教程。
