go語言的語法學(xué)起來還是比較快的诱鞠,但在實(shí)戰(zhàn)過程中總會遇到這樣或那樣的錯誤挎挖,逐個解決領(lǐng)悟之后,才能真正掌握go語言的細(xì)枝末節(jié)航夺,成為一名合格的gopher
蕉朵。
廢話不多說,先吃幾個栗子:
- 下面的變量定義是否正確阳掐?
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)
怎么樣,是不是找到一丟丟感覺了呀 : )
===============================
今天第一節(jié)(兒童節(jié)也闊以愉快的寫博客~)缭保,分享幾點(diǎn)defer
的細(xì)枝末節(jié):
Defer規(guī)則一:下面的語句會觸發(fā)panic嗎汛闸?
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("觸發(fā)異常")
}
【解析】當(dāng) defer
與 panic
處于同一個 goroutine
中,defer
會試圖去recover
(注釋部分)涮俄,此時由于沒有 recover
進(jìn)行捕獲蛉拙,因此會出現(xiàn)如下幾種輸出:
a.
“觸發(fā)異常”
“打印后”
“打印中”
“打印前”
b.
“打印后”
“打印中”
“打印前”
“觸發(fā)異吵骨祝”
c.
“打印后”
“觸發(fā)異吃谐”
“打印中”
“打印前”
出現(xiàn)以上幾種不同的輸出結(jié)果,筆者的理解(歡迎討論~)是打印到 stdout
的 print
函數(shù)在同一時刻爭搶的結(jié)果苞尝,因為程序的實(shí)際執(zhí)行順序是:遇到panic
畸肆,先執(zhí)行 defer
中 fmt.Println
后,再輸出 panic
自己的報錯宙址。
Defer規(guī)則二:當(dāng)defer
被聲明時轴脐,其參數(shù)就會被實(shí)時解析
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
}
【解析】當(dāng) defer 被調(diào)用時,a, b 會取當(dāng)前實(shí)時解析值,并先計算defer
里層 calc
的值保存下來大咱,最后再執(zhí)行defer
外層 calc
函數(shù)恬涧,因此輸出結(jié)果為:
10 1 2 3
20 0 2 2
2 0 2 2
1 1 3 4
Defer規(guī)則三:可以讀取有名返回值
package main
import "fmt"
func main() {
v := c()
fmt.Println(v)
}
func c() (i int) {
defer func() { i++ }()
return 1
}
【解析】當(dāng) defer
返回時,獲取到返回值 i = 1
碴巾,進(jìn)行 defer
里面的 i++
溯捆,所以返回輸出是2,而不是1厦瓢。
以上就是今天分享的關(guān)于 defer
的幾個point提揍,這些硬知識看書很容易忽略,在實(shí)戰(zhàn)中才能更好的掌握煮仇,keep moving~