关于go:interface {}到函数类型转换


interface{} to function type conversion

我是个新来的人,今天几乎一整天都在和这个问题作斗争。

考虑到我有这些:

1
2
3
type HandlerType func()
var object interface{}
var typedObject HandlerType

我可以这样给typedObject变量分配一个函数:

1
2
3
4
typedHandler = func() {
    fmt.Println("in a handler!
")
}

但我需要做的是将该处理程序函数作为接口变量传递,然后以某种方式将其转换为handlerType,稍后我可以调用它。

我已经尝试过了,但它抛出了一个错误:

1
typedHandler = object.(HandlerType)

结果:

interface conversion: interface is func(), not main.HandlerType

基本上,在注册之前,我需要注册具有不同签名的函数,而不需要进行额外的类型转换。所以不要这样做:

1
2
registerHandler(HandlerTypeString(func() string { ... }))
registerHandler(HandlerTypeVoid(func() { ... }))

我想注册这样的处理程序:

1
2
registerHandler(func() string { ... })
registerHandler(func() { ... })

…我不想在稍后处理程序调用时涉及反射

有可能吗?

编辑:我创建了一个操场:http://play.golang.org/p/ulwqkhjt_p

因此,据我所知,无法将某些任意函数作为接口传递,然后以某种方式将其转换为handlerType或其他预定义函数类型,这样我就可以在不使用反射的情况下调用它了?

edit2:我想出了这个解决方案:http://play.golang.org/p/4guxsgmipf

在运行时使用此代码不应该有任何性能惩罚。但是,有人能想出另一种方法来实现这个没有接口的功能吗?


你的问题中有许多小的误解:

  • 类型断言不用于强制转换类型。它所做的只是检查一个变量是否属于给定的类型,并将该变量作为这个基础类型返回。在您的情况下,此操作返回一个错误,这是正常的,因为func()不是HandlerFunc类型。

  • 在接受interface{}的函数中,不需要做任何事情来将变量作为参数传递。每个类型都隐式实现空接口。

  • func()不是HandlerType,即使HandlerTypetype HandlerType func()定义。这个定义与此无关。

  • 你想做的事是不可能的。我不是思考专家,但我认为思考也不能解决你的问题。

    也就是说,注册方法应该定义一个所有注册对象都应该实现的接口,并将此接口用作参数类型。以database/sqlRegister方法为例。


    你不能,它是不同的类型,你可以只使用object.(func())object.(func() string)等。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    func main() {
        type HandlerType func()
        var object interface{} = func() {
            fmt.Println("eureka!")
        }
        if f, ok := object.(func()); ok {
            HandlerType(f)()
        }
    }


    现在您可以使用reflect.makefunc完成此操作,这里有一个关于如何完成此操作的示例。