PowerGoose
PowerGoose

Reputation: 21

Multiple function types in a map, Golang

I hope to connect user input to functions. The user inputs are string. For example, "func_name=MyPrintf&s1=Hello, world\!" or "func_name=MyAdd&i1=1&i2=2"

Each function's code is,

func MyPrintf(s1 string) {
    fmt.Println(s1)
}

func MyAdd(i1, i2 int) {
    fmt.Println(i1, i2)
}

I want a map like below,

type Myfunc func(string) | func(int, int)   // <- Of course, it's wrong code, just I hope like this.

myMap := make(map[string]Myfunc)

myMap["MyPrintf"] = MyPrintf
myMap["MyAdd"] = MyAdd

myMap is possible to call function by func_name string from user input.

myMap[func_name](s1) Output: Hello, world! myMap[func_name](i1, i2) Output: 3

Is it possible? Maybe It's possible by using 'eval' I think, but I heard using 'eval' is not good. So, I thought using function pointer, however there's no function pointer in Golang.

I tried some generic programming for Golang,

type Myfunc interface {
    func(string) | func(int, int)
}

myMap := make(map[string]Myfunc)

Output: error occurred: cannot use type Myfunc outside a type constraint: interface contains type constraints

another try,

myMap := make(map[string]interface{})

myMap["MyPrintf"] = interface{}(MyPrintf)
myMap["MyPrintf"].(func(string))("Hello, world!")

Output: Hello, world!

myMap["MyAdd"] = interface{}(MyAdd)
myMap["MyAdd"].(func(int,int))(1, 2)

Output: 3

It works but must specify right func type, it's not comfortable. I think this way is not proper to my scenario. Please give me help. I'm sorry for my bad English writing.

Upvotes: 1

Views: 186

Answers (1)

Tomer S
Tomer S

Reputation: 1030

You can try this:

I must say it is not a good practice since panic \ error due to wrong types are not validated. I would consider another way to do so.

package main

import "fmt"

type GeneralFunc func(args ...interface{})

func main() {
    // Create a map of functions with the type GeneralFunc
    functionsMap := map[string]GeneralFunc{
        "MyPrintf": func(args ...interface{}) { fmt.Println(args[0].(string)) },
        "MyAdd":    func(args ...interface{}) { fmt.Println(args[0].(int), args[1].(int)) },
    }

    // Use the functions from the map
    functionsMap["MyPrintf"]("Hello World")
    functionsMap["MyAdd"](2, 3)
}

Upvotes: 3

Related Questions