這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Go函數是可以閉包的。閉包是一個函數值,他來自函數體外部的變數引用。
Go指南中有一篇例子,代碼如下
func adder() func(int) int { sum := 0 return func(x int) int { sum += x return sum }}func demoFunction2() { pos, neg := adder(), adder() for i := 0; i < 10; i++ { fmt.Println(pos(i), neg(-2 * i), ) }}
列印出的結果讓學java的我慌了,什麼情況
0 01 -23 -66 -1210 -2015 -3021 -4228 -5636 -7245 -90
按照我的固定思維,正確是結果應該是這樣的
0 01 -22 -43 -64 -85 -106 -127 -148 -169 -18
因為在java思維中,adder()函數給我們返回的就是另一個函數:
sum:=0func(x int) int { sum += x return sum }
實際上,在pos, neg := adder(), adder()的時候,pos和neg引用不僅得到了上面的那個閉包,也得到了sum這個在引用中的”常量”,所以實際上每次調用pos(i)和neg(-2 * i),都是改變了sum的值並存在pos引用對應的函數中了,可以在這個函數中加上一句代碼,讓整個過程更加直觀
return func(x int) int { fmt.Println(">>>>>>",sum) sum += x return sum }
當我們運行程式,再次列印結果,就會是下面的:
>>>>>> 0>>>>>> 00 0>>>>>> 0>>>>>> 01 -2>>>>>> 1>>>>>> -23 -6>>>>>> 3>>>>>> -66 -12>>>>>> 6>>>>>> -1210 -20>>>>>> 10>>>>>> -2015 -30>>>>>> 15>>>>>> -3021 -42>>>>>> 21>>>>>> -4228 -56>>>>>> 28>>>>>> -5636 -72>>>>>> 36>>>>>> -7245 -90
這下是不是更好理解了,以pos(i)為例,每次計算完之後,sum“常量”儲存了計算的結果:
函數 --- sum值 x值 return值 pos(0) --- 0 0 0 pos(1) --- 0 1 1 pos(2) --- 1 2 3 pos(3) --- 3 3 6 pos(4) --- 6 4 10 pos(5) --- 10 5 15 pos(6) --- 15 6 21 pos(7) --- 21 7 28 pos(8) --- 28 8 36 pos(9) --- 36 9 45
學習筆記,共勉
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。