3 回答

TA貢獻1805條經(jīng)驗 獲得超9個贊
這與返回閉包后變量如何封裝在閉包中有關(guān)??紤]以下示例(播放中的實時代碼):
func newClosure() func() {
i := 0
fmt.Println("newClosure with &i=", &i)
return func() {
fmt.Println(i, &i)
i++
}
}
func main() {
a := newClosure()
a()
a()
a()
b := newClosure()
b()
a()
}
運行此代碼將產(chǎn)生類似于以下輸出的內(nèi)容。我注釋了哪一行來自哪個語句:
newClosure with &i= 0xc010000000 // a := newClosure()
0 0xc010000000 // a()
1 0xc010000000 // a()
2 0xc010000000 // a()
newClosure with &i= 0xc010000008 // b := newClosure()
0 0xc010000008 // b()
3 0xc010000000 // a()
在示例中, 返回的閉包newClosure封裝了局部變量i。這對應(yīng)current于您的代碼中的等。你可以看到它a并b 有不同的 實例i,否則調(diào)用b()會被打印出來3。您還可以看到i變量具有不同的地址。(該變量已經(jīng)在堆上,因為 go 沒有單獨的堆棧內(nèi)存,所以在閉包中使用它完全沒有問題。)
因此,通過生成一個新的閉包,您會自動為該閉包創(chuàng)建一個新的上下文,并且局部變量不會在閉包之間共享。這就是為什么在循環(huán)中創(chuàng)建一個新的閉包不會讓你走得更遠的原因。
就本例而言,您的代碼的等效項是:
for i:=0; i < 10; i++ {
newClosure()()
}
并且您已經(jīng)從輸出中看到這是行不通的。
- 3 回答
- 0 關(guān)注
- 252 瀏覽
添加回答
舉報