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教程。