摘抄整理自《the way to go》
關(guān)鍵字defer
允許我們推遲到函數(shù)返回之前(或任意位置執(zhí)行return
語句之后)一刻才執(zhí)行某個語句或函數(shù)(為什么要在返回之后才執(zhí)行這些語句秕重?因為return
語句同樣可以包含一些操作器联,而不是單純地返回某個值)砰嘁。
關(guān)鍵字defer
的用法類似于面向?qū)ο缶幊陶Z言 Java 和 C# 的finally
語句塊,它一般用于釋放某些已分配的資源。
通常我們會將一些函數(shù)的收尾工作通過defer執(zhí)行沥邻,使代碼結(jié)構(gòu)更清晰。
package main
import "fmt"
func main() {
doDBOperations()
}
func connectToDB() {
fmt.Println("ok, connected to db")
}
func disconnectFromDB() {
fmt.Println("ok, disconnected from db")
}
func doDBOperations() {
connectToDB()
fmt.Println("Defering the database disconnect.")
defer disconnectFromDB() //function called here with defer
fmt.Println("Doing some DB operations ...")
fmt.Println("Oops! some crash or network error ...")
fmt.Println("Returning from function here!")
return //terminate the program
// deferred function executed here just before actually returning, even if
// there is a return or abnormal termination before
}
接下來看一些另類用法
使用 defer 語句實現(xiàn)代碼追蹤
package main
import "fmt"
//一個基礎(chǔ)但十分實用的實現(xiàn)代碼執(zhí)行追蹤的方案就是在進入和離開某個函數(shù)打印相關(guān)的消息,即可以提煉為下面兩個函數(shù):
func trace(s string) { fmt.Println("entering:", s) }
func untrace(s string) { fmt.Println("leaving:", s) }
func a() {
trace("a")
defer untrace("a")
fmt.Println("in a")
}
func b() {
trace("b")
defer untrace("b")
fmt.Println("in b")
a()
}
func main() {
b()
}
輸出:
entering: b
in b
entering: a
in a
leaving: a
leaving: b
上面的代碼還可以修改為更加簡便的版本
package main
import "fmt"
func trace(s string) string {
fmt.Println("entering:", s)
return s
}
func untrace(s string) {
fmt.Println("leaving:", s)
}
func a() {
defer untrace(trace("a"))
fmt.Println("in a")
}
func b() {
defer untrace(trace("b"))
fmt.Println("in b")
a()
}
func main() {
b()
}
使用 defer 語句來記錄函數(shù)的參數(shù)與返回值
下面的代碼展示了另一種在調(diào)試時使用 defer 語句的手法
package main
import (
"io"
"log"
)
func func1(s string) (n int, err error) {
defer func() {
log.Printf("func1(%q) = %d, %v", s, n, err)
}()
return 7, io.EOF
}
func main() {
func1("Go")
}
輸出:
Output: 2011/10/04 10:46:11 func1("Go") = 7, EOF
我是咕咕雞译柏,一個還在不停學(xué)習(xí)的全棧工程師。
熱愛生活罚缕,喜歡跑步艇纺,家庭是我不斷向前進步的動力。