Golang how to use a function as a map key

How to use the function as a card key? eg:

type Action func(int) func test(a int) { } func test2(a int) { } func main() { x := map[Action]bool{} x[test] = true x[test2] = false } 

this code will show an error: invalid map key type Action

+6
source share
5 answers

You cannot do this directly, as already mentioned, but you can fake it like this:

 package main import "fmt" func a(i int) int { return i + 1 } func b(i int) int { return i + 2 } type Function func(int)int type FunctionWrapper struct { f *Function } var fnMap = make(map[string]FunctionWrapper) // MakeFunctionWrapper returns a unique FunctionWrapper per Function pointer, using fnMap to avoid having multiple values for the same function func MakeFunctionWrapper(f Function) FunctionWrapper { key := fmt.Sprintf("%#v", f) data, ok := fnMap[key] if !ok { data = FunctionWrapper{&f} fnMap[key] = data } return data } func main() { functions := make(map[FunctionWrapper]bool) fa := MakeFunctionWrapper(a) fb := MakeFunctionWrapper(b) fb2 := MakeFunctionWrapper(b) functions[fa] = true functions[fb] = true functions[fb2] = false // This overwrites the previous value since fb is essentially the same as fb2 fmt.Println(functions[fa]) // "true" fmt.Println(functions[fb]) // "false" fmt.Println(functions[fb2]) // "false" } 

Check it out on the Go Playground

This is a bit cumbersome, and I honestly think that it is a very bad idea to essentially use a string version of the pointer as the map key. But ... this is at least an option if you really need it.

+2
source

You cannot use the function as a card key. The language specification clearly says:

Comparison operators == and! = Must be fully defined for key type operands; therefore, the key type should not be a function, map, or slice.

+11
source

You cannot use functions as keys on cards: the type of key must be comparable.

From Go To Blog :

Keys

can be of any comparable type. The language specification defines this precisely, but, in short, comparable types are Boolean, numeric, string, pointer, channel, and interface types, as well as structures or arrays that contain only those types. Noticeably not in the list. slices, cards, and features ; these types cannot be compared using ==, and cannot be used as a map key

What you can use, depending on your specific use case, is an interface.

+7
source

Functions cannot be:

Comparison operators == and! = Must be fully defined for key type operands; therefore, the key type should not be a function, map, or slice.

A source

+4
source

While functions cannot be keys, pointers to functions can.

 package main import "fmt" type strFunc *func() string func main() { myFunc := func() string { return "bar" } m := make(map[strFunc]string) m[(strFunc)(&myFunc)] = "f" for f, name := range m { fmt.Println((*f)(), name) } } 

http://play.golang.org/p/9DdhYduX7E

+2
source

Source: https://habr.com/ru/post/979033/


All Articles