Как понять этот рекурсивный результат

Я написал ошибку во время кодирования, когда я решил проблему, я был смущен выводом кода, код показан ниже:

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=486d40
after func h=486c00
return mh,name=main,h=486d40
********************************
before func h=486c00
after func h=486c00
return mh,name=main,h=486c00
return mh,name=main,h=486d40
********************************
before func h=486c00
after func h=486c00
return mh,name=main,h=486c00
return mh,name=main,h=486c00
return mh,name=main,h=486d40
.......

Я не понимаю стек вызовов. Я думал, что на выходе должен быть цикл "mh".

Стоит пройти через это с помощью delve и, возможно, также проверить вывод дизассемблирования. Это должно прояснить ситуацию

Elias Van Ootegem 13.01.2019 12:29
Что такое компоненты React? Введение в компоненты | Типы компонентов
Что такое компоненты React? Введение в компоненты | Типы компонентов
Компонент - это независимый, многократно используемый фрагмент кода, который делит пользовательский интерфейс на более мелкие части. Например, если мы...
4
1
135
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Виной всему это задание:

  h = mh(h) 

Он заменяет привязку h в main из анонимной функции, которая распечатывает до / после того, что возвращает mh.

Если вы замените

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

С участием

    return mh(h)(name)

Вы получите ожидаемую взаимную рекурсию

Когда я использую h = mh(h), почему происходит взаимная рекурсия?

dingdang 13.01.2019 18:38
Ответ принят как подходящий

Главное, что нужно понять, это то, что эта строка:

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, который теперь представляет собой функцию, обернутую дважды. Он начинается с печати "return", затем вызывает сохраненное значение h, которое является одноразовой функцией. Функция однократного обертывания начинается с печати "return" (снова), затем переходит к исходному, который печатает "before", обертывает h, который теперь будет трехкратно обернут, сохраняет его в h, затем вызывает h (который является 3- раз обернутое значение функции) ...

Эта логика продолжается, значение функции, хранящееся в h, будет все больше и больше обертываться, а обернутая функция всегда имеет сохраненное значение предыдущей функции, обернутой меньше одного раза.

По мере продолжения «итерации» «глубина упаковки» увеличивается, поэтому вы будете видеть все больше и больше напечатанных операторов "return" (как это и делает упаковка).

Другие вопросы по теме