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

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

如何理解這個遞歸結果

如何理解這個遞歸結果

Go
互換的青春 2023-06-01 14:58:36
我在編碼時寫了一個錯誤,當我解決這個問題時,我對代碼的輸出感到困惑,代碼如下所示:type (    Handler func(name string) error)func mh(h Handler) Handler {    return func(name string) error {        fmt.Printf("return mh,name=%s,h=%x\n", name, h)        return h(name)    }}func main() {    var h Handler    h = func(name string) error {        fmt.Printf("********************************\n")        fmt.Printf("before func h=%x\n", h)        h = mh(h)        fmt.Printf("after func h=%x\n", h)        return h(name)    }    fmt.Printf("main h=%x\n", h)    h("main")}運行代碼,輸出為:main h=486d40********************************before func h=486d40after func h=486c00return mh,name=main,h=486d40********************************before func h=486c00after func h=486c00return mh,name=main,h=486c00return mh,name=main,h=486d40********************************before func h=486c00after func h=486c00return mh,name=main,h=486c00return mh,name=main,h=486c00return mh,name=main,h=486d40.......我不明白調用堆棧。我認為輸出應該是循環“mh”。
查看完整描述

2 回答

?
三國紛爭

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

要理解的關鍵是這一行:

h = mh(h)

調用函數h。它調用mh()函數,該函數只返回一個函數值,但它不調用h()任何一個。如果將調用返回的函數值,那將調用h().

所以該main()函數將一個函數值存儲在 中h,然后調用h()

h()將打印"before",然后包裝 h在另一個函數中,并將結果存儲在h,然后打印"after"。重要的是要知道包裝函數(由 返回的值mh())是一個閉包,它存儲了 的原始值h,因此將結果分配給h不會影響h包裝函數內部。

所以h通過調用h現在是包裝函數來結束。包裝函數從打印開始"return",然后調用原始的未包裝函數h。

原始的,h再次展開打印"before",然后它包裝當前值h(這是包裝函數),將其存儲在中h,然后打印"after"

然后調用h,它現在是一個 2 次包裝函數。它從打印開始"return",然后調用保存的h值,這是一個 1 次包裝函數。1 次包裝函數從"return"(再次)打印開始,然后繼續原始函數,打印"before", wrapsh現在將被 3 次包裝,將其存儲在 中h,然后調用h(這是 3 次包裝函數值) ...

如此邏輯下去,存儲的函數值h會越來越wrapped,被wrapped的函數總是有一個少一次wrapped previous function的保存值。

隨著“迭代”的繼續,“包裝深度”增加,因此您會看到越來越多的"return"語句被打?。ㄒ驗檫@就是包裝的作用)。


查看完整回答
反對 回復 2023-06-01
?
暮色呼如

TA貢獻1853條經驗 獲得超9個贊

罪魁禍首是這個任務:

  h = mh(h)

它取代了在任何返回之前/之后打印出的匿名函數中的hin的綁定。mainmh

如果你更換

    h = mh(h)    
    fmt.Printf("after func h=%x\n", h)    
    return h(name)

    return mh(h)(name)

你會得到你期望的相互遞歸


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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