Mahi G
Mahi G

Reputation: 391

Map to store generic type functions in Go

I am trying to create a Map with String and functions as key and Value. It works if all functions are of same signature but my requirement is to store functions of different signature in the same map. Is this possible in Go?

package main

import "fmt"

func main() {

    functions := buildFunctions()
    f := functions["isInValid"]

    //  f("hello")

}

func buildFunctions() map[string]func() bool {

    functions := map[string]func() bool{
        "isInValid":   isInValid,
        "isAvailable": isAvailable,
    }
    return functions
}

func isInValid(s string) bool {
    fmt.Println("Invalid ", s)
    return true
}

func isAvailable(s string, s1 string) bool {
    return true
}

https://play.golang.org/p/ocwCgEpa_0G

Upvotes: 0

Views: 3757

Answers (1)

Tushar
Tushar

Reputation: 1155

Go is a strongly typed language. So, it's not possible the way, it is possible with, say python. But just like python, once you do this, you loose the benefit of compile time error checks, and your runtime error checking has to be full-proof. Here's what you can do:

  1. Use map[string]interface{} type for your function map, which enables you to store anything. But then you are responsible to correctly type assertion at the time of calling. Problem is that, in most cases, if while calling a function, you could know the type of function, may be you might not need a map in the first place.

  2. Use a map[string]string or map[string]interface{} as the argument, and return type in all the functions that are supposed to go into this map. Or at least put all the variable arguments into this map.

    eg.

    map[string](func (name string, age int, other_attributes map[string]interface{}) (map[string]interface{}, error))

But again, each function call should provide the correct arguments, and there should also be checks inside the functions, to see (with non-panic version of map lookup), if the parameters are correctly provided, if not, you can return a custom error like ErrInvalidParametersPassed. (playing the role of an interpreter). But you will still have lesser chances of messing up, compared to first option. As the burden of type assertion will be on the function implementation, and not the caller. Caller just needs to fetch it's required values, which it anyways needs to know about.

But yet, best option would be to redesign your actual solution in a way, so that it can be done without going this road. As @bereal suggested in comments, it's good to have separate maps if possible, or maybe use a superset of arguments if they aren't too different, or too many. If there are just a few arguments, even switch case could be clean enough. Look for ways that cheat/bypass compile time checks, when you are truly convinced that there is no other elegant way.

Upvotes: 1

Related Questions