go - 在 Go 中将任意函数作为参数传递

标签 go decorator function-pointers

我正在尝试扩展我对 Go 函数指针的了解,我有一个问题,关于在 Go 中将函数作为参数传递什么是可能的,什么是不可能的。

假设我想编写一个可以包装任何现有函数的decorator() 函数。为简单起见,我们将其限制为仅接受一个参数并返回一个值的函数。

如果我编写一个接受 func(interface{}) interface{} 作为参数的装饰器,只要我传入的函数也接受/返回一个 ,它就会隐式工作interface{} 类型(参见 funcA)。

我的问题是——有没有一种方法可以将 func(string) string 类型的现有函数转换为 func(interface{}) 接口(interface)类型{} 这样它也可以被传递到装饰器函数中,而不只是将它包装在一个新的匿名函数中(参见 funcB)?

package main

import (
    "fmt"
)

func decorate(inner func(interface{}) interface{}, args interface{}) interface {} {
    fmt.Println("Before inner")
    result := inner(args)
    fmt.Println("After inner")
    return result
}

func funcA(arg interface{}) interface{} {
    fmt.Print("Inside A, with arg: ")
    fmt.Println(arg)
    return "This is A's return value"
}

func funcB(arg string) string {
    fmt.Print("Inside B, with arg: ")
    fmt.Println(arg)
    return "This is B's return value"
}

func main() {
    
    // This one works. Output is:
    //
    //   Before inner
    //   Inside A, with arg: (This is A's argument)
    //   After inner
    //   This is A's return value
    //
    fmt.Println(decorate(funcA, "(This is A's argument)"))
    
    // This doesn't work. But can it?
    //fmt.Println(decorate(funcB, "(This is B's argument)"))
}

最佳答案

这是不可能的。原因之一是传递参数的机制因函数而异,使用 interface{} arg 并不意味着“接受任何东西”。例如,将结构作为 arg 的函数将接收该结构的每个成员,但是将包含该结构的接口(interface){}作为参数的函数将接收两个单词,一个包含结构的类型,另一个包含指向的指针

因此,在不使用泛型的情况下,实现这一点的唯一方法是使用适配器函数。

关于go - 在 Go 中将任意函数作为参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69759462/

相关文章:

c - 我不知道错误是什么

c - 集成函数指针

go - 在 golang 的字符串数组中打印特定字节的值

go - 如何始终通过无效 key 类型错误生成 JWT token

python - 如何在不使用 @ 语法的情况下使用 "double layered"装饰器?

python - 手动调用带参数的装饰器

c++ - 如何使指针指向派生类的成员函数

json 字段标签内的 Golang 变量

go - 为什么 Golang http 参数 (URL.Query()) 是列表的映射?

python - 装饰器错误 : NoneType object is not callable