這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
閉包是什麼,閉包是由函數及其相關的引用環境組合而成的實體(即:閉包=函數+引用環境)。
有關這部分可以參看:http://www.cnblogs.com/ghj1976/archive/2013/02/08/2909364.html
閉包包含著外部的環境變數值,但這個環境變數值並不像匿名函數那樣作為參數副本,而是實實在在在的引用(或者指標,反正一個意思),當外部變數變化時,閉包能使用的值自然也就變化了。
根據這個原理,下面羅列的幾個閉包情境為何計算值是對應的值就很清楚了。
下面例子來自: http://blog.csdn.net/liugao15/article/details/8296064
例子1
package main
import"fmt"
func main(){
var fn [10]func()
for i:=0;i<len(fn);i++{
fn[i]=func(){
fmt.Println(i)
}
}
for_,f:=rangefn{
f()
}
}
輸出值:
10
10
10
10
10
10
10
10
10
10
exit code 0, process exited normally.
原理:在執行f() 時,i 用的是之前定義的 i 的指標,由於之前已經完成了迴圈,這時候全部顯示的是10.
例子2
package main
import "fmt"
func main(){
var fn [10]func(int)
for i:=0;i<len(fn);i++{
fn[i]=make_fn()
}
for i,f:=range fn{ // 閉包中使用的是這個ide指標
f(i)
}
}
fund make_fn() func(i int){
return func(i int){
fmt.Println(i)
}
}
輸出:
0
1
2
3
4
5
6
7
8
9
exit code 0, process exited normally.
下面例子來自:http://lelouchhe.github.com/one_thing_about_closure_in_go/
例子3
package main
import(
"fmt"
"time"
)
func main(){
for i:=0;i<100;i++{
go func(){
fmt.Println(i)
}()
}
time.Sleep(1e9)
}
這個輸出結果全部是100,因為這個迴圈啟動並執行比goroutine還快,goroutine還沒有開始,for迴圈已經結束了,此時i的值就是100了,所以閉包內的i自然就是100.