go語言的語法學起來仍是比較快的,但在實戰過程當中總會遇到這樣或那樣的錯誤,逐個解決領悟以後,才能真正掌握go語言的細枝末節,成爲一名合格的gopher
。app
廢話很少說,先吃幾個栗子:函數
var a int, b int, c int
複製代碼
package main
s := "china"
func main() {
}
複製代碼
s := make([]int, 5)
s = append(s, 1, 2, 3)
fmt.Println(s)
複製代碼
怎麼樣,是否是找到一丟丟感受了呀 : )ui
===============================spa
今天第一節(兒童節也闊以愉快的寫博客~),分享幾點defer
的細枝末節:code
func main() {
deferCall()
}
func deferCall() {
defer func() {
fmt.Println("打印前")
/*if err := recover(); err != nil { fmt.Println(err) }*/
}()
defer func() { fmt.Println("打印中") }()
defer func() { fmt.Println("打印後") }()
panic("觸發異常")
}
複製代碼
【解析】當 defer
與 panic
處於同一個 goroutine
中,defer
會試圖去recover
(註釋部分),此時因爲沒有 recover
進行捕獲,所以會出現以下幾種輸出:orm
a.
「觸發異常」
「打印後」
「打印中」
「打印前」
b.
「打印後」
「打印中」
「打印前」
「觸發異常」
c.
「打印後」
「觸發異常」
「打印中」
「打印前」
複製代碼
出現以上幾種不一樣的輸出結果,筆者的理解(歡迎討論~)是打印到 stdout
的 print
函數在同一時刻爭搶的結果,由於程序的實際執行順序是:遇到panic
,先執行 defer
中 fmt.Println
後,再輸出 panic
本身的報錯。cdn
defer
被聲明時,其參數就會被實時解析func calc(index string, a, b int) int {
ret := a + b
fmt.Println(index, a, b, ret)
return ret
}
func main() {
a := 1
b := 2
defer calc("1", a, calc("10", a, b))
a = 0
defer calc("2", a, calc("20", a, b))
b = 1
}
複製代碼
【解析】當 defer 被調用時,a, b 會取當前實時解析值,並先計算defer
裏層 calc
的值保存下來,最後再執行defer
外層 calc
函數,所以輸出結果爲:博客
10 1 2 3
20 0 2 2
2 0 2 2
1 1 3 4
複製代碼
package main
import "fmt"
func main() {
v := c()
fmt.Println(v)
}
func c() (i int) {
defer func() { i++ }()
return 1
}
複製代碼
【解析】當 defer
返回時,獲取到返回值 i = 1
,進行 defer
裏面的 i++
,因此返回輸出是2,而不是1。string
以上就是今天分享的關於 defer
的幾個point,這些硬知識看書很容易忽略,在實戰中才能更好的掌握,keep moving~it