您好,登錄后才能下訂單哦!
和變量的聲明不同,Go語言不能在函數里聲明另外一個函數。所以在Go的源文件里,函數聲明都是出現在最外層的。
“聲明”就是把一種類型的變量和一個名字聯系起來。
Go里有函數類型的變量,這樣,雖然不能在一個函數里直接聲明另一個函數,但是可以在一個函數中聲明一個函數類型的變量,此時的函數稱為閉包(closure)。
例:
packagemain
import"fmt"
funcmain(){
add:=func(baseint)func(int)(int){
returnfunc(iint)(int){
returnbase+i
}
}
add5:=add(5)
fmt.Println("add5(10)=",add5(10))
}
這個例子唯一的使用價值大概就是用來展示閉包的構建和使用。
add是一個閉包,因為它是無名的函數類型的變量。可以認為它是一個閉包作坊,根據入參返回(生產)一個閉包。這樣add5就是使用5作為add的參數得到的一個閉包。
閉包的聲明是在另一個函數的內部,形成嵌套。和塊的嵌套一樣,內層的變量可以遮蓋同名的外層的變量,而且外層變量可以直接在內層使用。如add的base參數在return返回的閉包的外層,所以它的值5在add返回并賦值給add5后依舊存在。當add5執行時,參數i可以從這個外層得到的base相加,得到結果15.
個人理解:
其實理解閉包的最方便的方法就是將閉包函數看成一個類,一個閉包函數調用就是實例化一個類。
然后就可以根據類的角度看出哪些是“全局變量”,哪些是“局部變量”了。
比如上例中的adder函數返回func(int) int 的函數
pos和neg分別實例化了兩個“閉包類”,在這個“閉包類”中有個“閉包全局變量”sum。所以這樣就很好理解返回的結果了。
再來看下面一個例子:
import "fmt"
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
func main() {
pos, neg := adder(), adder()
for i := 0; i < 10; i++ {
fmt.Println(
pos(i),
neg(-2*i),
)
}
}
運行返回結果:
0 0 1 -2 3 -6 6 -12 10 -20 15 -30 21 -42 28 -56 36 -72 45 -90
這個就是Go中的閉包,一個函數和與其相關的引用環境組合而成的實體。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。