为了账号安全,请及时绑定邮箱和手机立即绑定

如何理解这个递归结果

如何理解这个递归结果

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 关注
  • 81 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信