Почему порядок выполнения функций кажется обратным, когда я добавляю вызовы функций? - PullRequest
0 голосов
/ 08 февраля 2019

Я читал этот вопрос: Функции декоратора в Go и мне интересно, почему порядок выполнения примера в принятом ответе мне кажется обратным.

Я разбил его наследующий минимальный пример, и мне интересно, если эффект вызван цепочкой функцийфункции оцениваются от самого внутреннего к внешнему, то есть справа налево.[Это напоминает мне о постмножении матриц преобразования - там порядок также «обратный», т. Е. M_1 * M_2 * M_3] Это из-за цепочки функций или в чем причина?Может ли кто-нибудь помочь мне понять, как это выполняется в деталях?

Заранее спасибо.

1 Ответ

0 голосов
/ 08 февраля 2019

Я переписал ваш пример для иллюстрации.

Вызовы вложенных функций выполняются изнутри наружу.Каждый вызов функции возвращает функцию.В конце концов, переменной m присваивается результат AppendDecorator, который сам является функцией, составленной из всех декораторов, которые выглядят примерно так:

m := func(s string) string {
    return ("DECORATED " + strings.ToLower(s + " GOLANG"))
}

Когда мы выполняем m(s) (внутри fmt.Println(m(s)) мы выполняем функцию, возвращаемую AppendDecorator.Эта функция вызывает m(s + x), где m - функция, возвращаемая ToLower.Когда эта функция выполняется, она вызывает m(lower), где m - функция, возвращаемая PrependDecorator.Когда эта функция выполняется, она вызывает m(x + s), где m - это функция идентификации, которую мы передали.

package main

import (
    "fmt"
    "strings"
)

// StringManipulator manipulate a string
type StringManipulator func(str string) string

// Identity a string manipulator that leaves the string unchanged
func Identity(s string) string {
    fmt.Println("Executing Identity manipulator")
    return s
}

// ToLower a lower case string manipulator
func ToLower(m StringManipulator) StringManipulator {
    fmt.Println("Returning ToLower manipulator")
    return func(s string) string {
        fmt.Println("Executing ToLower manipulator")
        lower := strings.ToLower(s)
        return m(lower)
    }
}

// AppendDecorator append a string manipulator
func AppendDecorator(x string, m StringManipulator) StringManipulator {
    fmt.Println("Returning Append manipulator")
    return func(s string) string {
        fmt.Println("Executing Append manipulator")
        return m(s + x)
    }
}

// PrependDecorator prepend a string manipulator
func PrependDecorator(x string, m StringManipulator) StringManipulator {
    fmt.Println("Returning Prepend manipulator")
    return func(s string) string {
        fmt.Println("Executing Prepend manipulator")
        return m(x + s)
    }
}

func main() {
    s := "Some_String"

    m := AppendDecorator(" GOLANG", ToLower(PrependDecorator("DECORATED ", Identity)))
    fmt.Println(m(s))
}

Выходные данные m := AppendDecorator(" GOLANG", ToLower(PrependDecorator("DECORATED ", Identity))):

Returning Prepend manipulator
Returning ToLower manipulator
Returning Append manipulator

ивывод из fmt.Println(m(s)):

Executing Append manipulator
Executing ToLower manipulator
Executing Prepend manipulator
Executing Identity manipulator
DECORATED some_string golang
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...