How to use function as map's key? for example:
type Action func(int)
func test(a int) { }
func test2(a int) { }
func main() {
x := map[Action]bool{}
x[test] = true
x[test2] = false
}
those code would show an error: invalid map key type Action
You can use reflect
.
import (
"reflect"
"math"
)
func foo () {
table := make(map[uintptr] string)
table[reflect.ValueOf(math.Sin)] = "Sin"
table[reflect.ValueOf(math.Cos)] = "Cos"
println(table[reflect.ValueOf(math.Cos)])
}
You cannot use a function as a map key. The language specification clearly says:
The comparison operators == and != must be fully defined for operands of the key type; thus the key type must not be a function, map, or slice.
You can't use functions as keys in maps : the key type must be comparable.
From Go blog :
map keys may be of any type that is comparable. The language spec
defines this precisely, but in short, comparable types are boolean,
numeric, string, pointer, channel, and interface types, and structs or
arrays that contain only those types. Notably absent from the list are
slices, maps, and functions; these types cannot be compared using ==,
and may not be used as map key
What you might use, depending on your precise use case, is an interface.
Functions cannot be keys:
The comparison operators == and != must be fully defined for operands of the key type; thus the key type must not be a function, map, or slice.
Source
You cannot do this directly, as mentioned already, but you can sort of fake it you do something 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 it's a very bad idea to essentially use the string version of a pointer as your map's key. But ... it's at least an option if you really need it.
While functions can't be keys, function pointers 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