閉包環境中引用的變量是不能夠在棧上分配的,而是在堆上分配。因為如果引用的變量在棧上分配,那么該變量會跟隨函數f返回之后回收,那么閉包函數就不可能訪問未分配的一個變量,即未聲明的變量,之所以能夠再堆上分配,而不是在棧上分配,是Go的一個語言特性----escape analyze(能夠自動分析出變量的作用范圍,是否將變量分配堆上)。
閉包的底層實現
Go在底層使用類似結構體的形式表示一個閉包。
我們可以把上面的閉包表示成這樣,即:
type Closure struct{ func()() //匿名函數地址,當然語法要求一定要有變量名,這里只是為了表達匿名的含義 i *int //引用的變量地址 }
小結
-
Go語言支持閉包
-
Go語言能通過escape analyze識別出變量的作用域,自動將變量在堆上分配。將閉包環境變量在堆上分配是Go實現閉包的基礎。
-
返回閉包時並不是單純返回一個函數,而是返回了一個結構體,記錄下函數返回地址和引用的環境中的變量地址。