亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Golang 在編寫函數閉包時會自動將變量分配為參數嗎?

Golang 在編寫函數閉包時會自動將變量分配為參數嗎?

Go
湖上湖 2023-07-10 17:55:02
這是我引用的代碼:package mainimport "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我不明白函數中的語句x是如何分配的?它似乎沒有在函數中的任何地方傳遞。我也不明白這個變量是如何工作的。每次調用該函數并為其賦值時,不應該重置它嗎?returnaddersumadder0
查看完整描述

2 回答

?
藍山帝景

TA貢獻1843條經驗 獲得超7個贊

Go 以非常典型/標準的方式處理一流的函數和閉包。在這種情況下,調用adder自身:

  1. 創建以 valueint命名的對象。sum0

  2. 返回一個閉包:一個類似函數的東西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 上的完整代碼。


查看完整回答
反對 回復 2023-07-10
?
汪汪一只貓

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)

查看完整回答
反對 回復 2023-07-10
  • 2 回答
  • 0 關注
  • 155 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號