【问题标题】:Type of a function variable in GoGo中函数变量的类型
【发布时间】:2013-08-08 04:10:15
【问题描述】:

我想写一个函数,它接受一个指向任何类型函数的指针。我可以这样做:

func myFunc(f interface{})

...但这将允许非函数值。有什么方法可以将类型限制为任何函数?

【问题讨论】:

  • 除了interface{}之外,所有函数类型都没有“超类型”,所以这是你能做的最好的。

标签: types go function-pointers higher-order-functions


【解决方案1】:

假设您的字面意思是 any 功能,您可以进行类型切换(具体而言):

switch v.(type) {
case func() int:
case func() string:
}

或者您可以使用reflect 包来确定类型:

if reflect.TypeOf(v).Kind() != reflect.Func {
    // error here
}

这是一个运行时解决方案。除此之外,你无能为力。这样做的缺点是编译器不会阻止某人传递非函数值。

我个人会避免这样做,我希望有一个特定的 func 原型,例如:

func myFunc(f func() string)

这样,当编译器知道类型是什么时,您就不太可能出错。

【讨论】:

    【解决方案2】:

    Go 中的函数是 first class citizens。因此它们可以像任何其他类型一样传递给函数并从函数返回。

    你可以定义你的函数以函数作为它的参数。

    阅读更多 - First class functionsFirst class functions in Go

    【讨论】:

    • 我的用例更像这样:我想要一个函数,func takesFunc(f func()),并且能够传入任何函数(不管参数和返回类型)。您所说的将允许我接受一种特定类型的函数(即func(int) intfunc(bool) (string, int)),但不能接受任何任意函数类型。
    【解决方案3】:

    “任意函数”的概念可以在 Go 中分两步构建:

    type MotherOfAllFuncs func()
    

    下一步是将 any 函数包装在一个闭包中,作为匿名类型,它与 MotherOfAllFuncs 的赋值兼容。

    func() {
            anyFunction(with, any, parameters)
    }
    

    package main
    
    import "fmt"
    
    type f func()
    
    func g(f f) {
            f()
    }
    
    func h(i int) {
            fmt.Println(21 * i)
    }
    
    func i() {
            fmt.Println(314)
    }
    
    func main() {
            g(func() { h(2) })
            g(func() { i() })
    }
    

    Playground


    输出:

    42
    314
    

    【讨论】:

    • 我知道你从哪里来,这在技术上是可行的,但它确实是 hack-y。如果我这样做,我还不如在接受函数中进行反射检查。
    猜你喜欢
    • 1970-01-01
    • 2017-04-15
    • 1970-01-01
    • 2012-03-13
    • 2019-05-25
    • 2013-03-22
    • 2019-04-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多