2 回答

TA貢獻1843條經驗 獲得超7個贊
Go 以非常典型/標準的方式處理一流的函數和閉包。在這種情況下,調用adder
自身:
創建以 value
int
命名的對象。sum
0
返回一個閉包:一個類似函數的東西1,當被調用時,可以訪問變量
sum
。
返回的特定類似函數的東西adder
(其調用者在普通變量中捕獲)是一個帶有一個參數的函數。然后你調用它,傳遞一個參數。這種參數傳遞沒有什么特別之處:它的工作方式與其他地方相同。在類似函數的東西中,使用變量x
可以獲取調用者傳遞的值。使用名稱sum
可以獲取捕獲的int
對象,無論其值是什么。從函數返回后,捕獲的內容int
仍然被捕獲,因此稍后調用相同的類似函數的東西會看到int
中的更新sum
。
通過調用adder
兩次,您會得到兩個略有不同的類似函數的東西:每個都有自己的私有sum
.?這兩個 privatesum
最初都為零。調用您保存了值的類似函數的東西pos
可以獲得使用其中之一的函數。調用稍微不同的類似函數的東西,你保存了它的值,neg
你就可以得到使用另一個函數的函數。
1這個“類似函數的東西”和實際的函數之間沒有真正的區別,只是這個特定的類似函數的東西沒有可以調用它的名稱。這或多或少就是擁有一流功能的含義。
如果您遇到可讀性問題......
其原始形式是:
func adder() func(int) int {
? ? sum := 0
? ? return func(x int) int {
? ? ? ? sum += x
? ? ? ? return sum
? ? }
}
讓我們用一些類型名稱和其他語法更改來重寫它,使代碼的核心保持不變。首先,讓我們起一個名字,意思是func(int) int:
type adderClosure func(int) int
然后我們可以用它來重寫adder第一行:
func adder() adderClosure {
? ? ...
}
現在讓我們在加法器中創建一個局部變量來保存我們要返回的函數。為了明確和冗余,我們可以再次使用這種類型:
? ? var ret adderClosure // not good style: just for illustration
現在讓我們通過執行以下操作將該變量分配給我們的閉包:
? ? sum := 0
? ? ret = func(x int) int {
? ? ? ? sum += x
? ? ? ? return sum
? ? }
然后我們可以return ret
返回閉包。?這是 Go Playground 上的完整代碼。

TA貢獻1898條經驗 獲得超8個贊
當您分配和時,該sum變量位于兩個閉包中。閉包中的是通過添加 1, 2, 3, 4(斐波那契風格)來更新的,而閉包中的是通過在每次循環迭代中減去 2*1, 2*2, 2*3, 2*4 來更新的。posnegsumpossumneg
或者,更詳細地說: pos := adder()分配給一個函數,該函數具有從0 開始的pos閉包。然后每當您調用該函數時,它都會相應更新。和任何其他類似的作業也是如此。sumsumpossumneg
以下是一些類似(更簡單)的 JavaScript 代碼,可在瀏覽器控制臺中運行:
function adder() {
? var sum = 0;
? return function(i) {
? ? sum += i;
? ? return sum;
? }
}
var pos = adder();
console.log( pos(1) ); // add 1 to 0 (1)
console.log( pos(2) ); // add 2 to 1 (3)
console.log( pos(3) ); // add 3 to 3 (6)
console.log( pos(4) ); // add 4 to 6 (10)
- 2 回答
- 0 關注
- 155 瀏覽
添加回答
舉報