defer使用場景
defer在Go語言中是一個十分常用的關鍵字,它的作用是:將其后面跟隨的語句進行延遲處理
簡單來說,就是程序先去干別的事情。最后再來做defer后面跟的東西
於是我們很容易就想到,defer可以用很多使用的場景
比如:
文件的關閉,資源的清理,解鎖及記錄時間,以及recover的使用
defer的一些特性
-
類似於棧的特性,所有的defer 語句都會像棧一樣先進后出
-
執行時機:Go語言中的return語句並不是一個原子操作,它分為給返回值賦值和RET指令兩步,而defer語句執行的時機其實就在返回值賦值操作之后,RET指令執行之前,如下圖
兩道defer面試題
func f1() int { //返回值沒有取名
x := 5
defer func() {
x++
}()
return x //1.返回值賦值 2.defer 3.執行RET返回 //開辟了一份空間 return語句先將5賦值給x defer修改了x的值 但是RET命令執行的對象還是那個‘5’
}
func f2() (x int) { //返回值有名字
defer func() {
x++
}()
return 5 //修改的是x的值
}
func f3() (y int) {
x := 5
defer func() {
x++
}()
return x //y = x = 5 defer修改的是 x 真正返回的y還是5
}
func f4() (x int) {
defer func(x int) {
x++ //改的是函數值的副本 //如果這里是 defer func(x *int) { x ++ }(x)
}(x) //那么結果就會變成6
return 5
}
func main() {
fmt.Println(f1()) //5
fmt.Println(f2()) //6
fmt.Println(f3()) //5
fmt.Println(f4()) //5
}
func main() {
x := 1
y := 2
defer calc("AA", x, calc("A", x, y))
x = 10
defer calc("BB", x, calc("B", x, y))
y = 20
//1.調用calc中的calc("A",x,y) 輸出:"A",1,2,3 因為函數調用時會確定每個參數的值
//2.defer calc("AA",x,3)
//3.調用第二個calc中的calc("B",x,y) 此時x y是20 輸出:"B",10,2,12
//4.defer calc("BB",x,12)
//5.先進后出 調用第二個calc 輸出:"BB",10,12,22
//6.調用第二個calc 輸出:"AA" 1,3,4
}