PHP和Go中的閉包變量作用域
阿新 • • 發佈:2019-01-04
reac 繼續 循環 我們 get .com https Golan 例子
關於閉包函數,之前在聊過。這裏忽略了一點,不管是Go/Php/Python,閉包都存在局部變量的引用。
我們還是先看個例子:
PHP示例:
$list = []; for ($i = 0; $i < 3; $i++) { $list[] = function(){ global $i; return $i; }; } foreach ($list as $fun) { echo $fun().PHP_EOL; }
以上輸出:
3 3 3
相信很多朋友會說:不是應該輸出 0 1 2嗎?
好,繼續,我們來看一個Golang的閉包示例:
package main import"fmt" func main() { var list []func() int for i := 0; i < 3; i++ { list = append(list, func() int { return i }) } for _, fun := range list { fmt.Printf("%p = %v\n", fun, fun()) } }
以上輸出:(這裏輸出的內存地址會根據機器的不同而有所不同,甚至相同的程序在不同的機器上執行後也會有不同的內存地址)
0x48fd70 = 30x48fd70 = 3 0x48fd70 = 3
有興趣的博友可以寫個同樣的Python示例,相信結果同出一轍。那麽為什麽結果是 3?
重點:閉包函數在調用完畢後,i變量就是從循環條件中的 i++開始,也就是 原本是 0,1,2循環結束,那麽閉包調用結束後此時 i從i++開始也就是3.
其實這個不難理解:
PHP:
$list = []; for ($i = 0; $i < 3; $i++) { echo $i.PHP_EOL; // 輸出 0 1 2 } echo $i.PHP_EOL;// 輸出 3
GO:
package main import "fmt" func main() {var i int for i = 0; i < 3; i++ { fmt.Printf("i = %v\n", i) } fmt.Printf("i = %v\n", i) }
i = 0 i = 1 i = 2 i = 3
結論:循環結束後變量i 從i++開始。
PHP和Go中的閉包變量作用域