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

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

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

Go
米脂 2023-06-05 17:38:07
我已将其分解为以下最小示例,并且想知道该效果是否是由于函数链接造成的。// Interesting Partsome_string := "Some_String"var fn3 StringManipulator = identfn3 = AppendDecorator(" GOLANG", ToLower(PrependDecorator("DECORATED ", fn3)))fmt.Println(fn3(some_string))// Prints "DECORATED some_string golang"// Function Definitionsfunc 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] 这是由于函数链接还是什么原因?有人可以帮助我详细了解这是如何执行的吗?
查看完整描述

1 回答

?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

我重写了你的例子来说明。


嵌套函数调用从内到外执行。每个函数调用返回一个函数。最终变量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 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


查看完整回答
反对 回复 2023-06-05
  • 1 回答
  • 0 关注
  • 120 浏览
慕课专栏
更多

添加回答

举报

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