为什么追加函数调用时函数执行顺序似乎颠倒了?

我已将其分解为以下最小示例,并且想知道该效果是否是由于函数链接造成的。


// Interesting Part

some_string := "Some_String"

var fn3 StringManipulator = ident

fn3 = AppendDecorator(" GOLANG", ToLower(PrependDecorator("DECORATED ", fn3)))

fmt.Println(fn3(some_string))

// Prints "DECORATED some_string golang"


// Function Definitions

func ToLower(m StringManipulator) StringManipulator {

    return func(s string) string {

        lower := strings.ToLower(s)

        return m(lower)

    }

}


func AppendDecorator(x string, m StringManipulator) StringManipulator {

        return func(s string) string {

            return m(s + x)

        }

}


func PrependDecorator(x string, m StringManipulator) StringManipulator {

    return func(s string) string {

        return m(x + s)

    }

}

如代码中所述,这会产生“DECORATED some_string golang”,表明函数是从左到右执行的,而普通函数是从最内层到最外层计算的,即从右到左。[这让我想起了变换矩阵的后乘——顺序也被“颠倒”了,即 M_1 * M_2 * M_3] 这是由于函数链接还是什么原因?有人可以帮助我详细了解这是如何执行的吗?


米脂
浏览 121回答 1
1回答

小唯快跑啊

我重写了你的例子来说明。嵌套函数调用从内到外执行。每个函数调用返回一个函数。最终变量m被赋值,其结果AppendDecorator本身就是一个由所有装饰器组成的函数,看起来像这样:m := func(s string) string {    return ("DECORATED " + strings.ToLower(s + " GOLANG"))}当我们执行m(s)(内部fmt.Println(m(s))时,我们正在执行由返回的函数AppendDecorator。此函数调用m(s + x)where mis 返回的函数ToLower。当这个函数执行时,它调用m(lower)where is where mis the function by 返回PrependDecorator。当这个函数执行时,它会调用m(x + s)我们m传入的 Identity 函数。package mainimport (    "fmt"    "strings")// StringManipulator manipulate a stringtype StringManipulator func(str string) string// Identity a string manipulator that leaves the string unchangedfunc Identity(s string) string {    fmt.Println("Executing Identity manipulator")    return s}// ToLower a lower case string manipulatorfunc 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 manipulatorfunc 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 manipulatorfunc 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 manipulatorReturning ToLower manipulatorReturning Append manipulator输出fmt.Println(m(s))是:Executing Append manipulatorExecuting ToLower manipulatorExecuting Prepend manipulatorExecuting Identity manipulatorDECORATED some_string golang
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go