我正在阅读以下问题:Decorator functions in Go,并且想知道为什么在接受的答案中示例的执行顺序似乎与我相反。
我已将其分解为以下最小示例,并且想知道其效果是否是由于函数链接引起的。
// 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]这是由于函数链接还是原因?有人可以帮我了解它如何详细执行吗?
谢谢。
答案 0 :(得分:1)
我重写了您的示例进行说明。
嵌套函数调用从内部到外部执行。每个函数调用都返回一个函数。最终,为变量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
是我们传入的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