defer問題——面試Go必看

go_9發表於2019-02-22

首先分享一段面試程式碼

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
}

請問這段程式碼能列印出什麼?

答案

10 1 2 3
20 0 2 2
2 0 2 2
1 1 3 4

解釋

在一個函式內如果有多個defer語句,那麼這些defer語句並不會馬上執行,而是會進入一個棧,函式return前,會按先後出的順序執行。也說是說最先被定義的defer語句最後執行。

所以,defer calc("2", a, calc("20", a, b))會先於defer calc("1", a, calc("10", a, b))執行。但是大家注意一點,這兩個defer語句calc函式內還有calc函式。所以,先要執行兩個calc函式內的calc函式。當這兩個內函式執行完畢,再按照順序執行其他程式碼。

關於defer和閉包的一些原理可以參考這兩篇文章

相關文章