Simplify casting in Go when taking any interface as a parameter

Issue

I have a struct like so,

//
// HandlerInfo is used by features in order to register a gateway handler
type HandlerInfo struct {
    Fn     func(interface{})
    FnName string
    FnRm   func()
}

where I want to pass a func:

func StarboardReactionHandler(e *gateway.MessageReactionAddEvent) {
 // foo
}

i := HandlerInfo{Fn: StarboardReactionHandler}

Unfortunately, this results in:

Cannot use 'StarboardReactionHandler' (type func(e *gateway.MessageReactionAddEvent)) as the type func(interface{})

I found this workaround:

func StarboardReactionHandler(e *gateway.MessageReactionAddEvent) {
 // foo
}

func handlerCast(e interface{}) {
    StarboardReactionHandler(e.(*gateway.MessageReactionAddEvent))
}

i := HandlerInfo{Fn: handlerCast}

Is there some way that I can simplify needing handlerCast, such as doing it inside my StarboardReactionHandler or in HandlerInfo? Maybe with generics or reflection? I basically just want to minimize the syntax / boilerplate that’s required here.

Solution

you can use interface{}.(type)

follow is a exmple:

package main

import "fmt"

type HandlerInfo struct {
    Fn     func(interface{})
    FnName string
    FnRm   func()
}
type MessageReactionAddEvent = func(a, b int) int

func StarboardReactionHandler(e interface{}) {
    switch e.(type) {
    case MessageReactionAddEvent:
        fmt.Printf("%v\n", (e.(MessageReactionAddEvent))(1, 2))
    }

}
func add(a, b int) int {
    return a + b
}
func main() {
    i := HandlerInfo{Fn: StarboardReactionHandler}
    i.Fn(add)
}

Answered By – Para

Answer Checked By – Senaida (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.