I am trying to create a function which takes in a map
as a parameter, where the map uses string
keys but the values can be ANY type.
How do I make this work in go? I tried using map[string]interface{}
as the parameter type to the function but that does not seem to work for example when passing in a map[string]int
as an argument.
Any explanations as to what is the problem with this approach and if there is a way to achieve this in go?
If a function parameter is of type map[string]interface{}
then you need to pass it a map[string]interface{}
(and map[string]int
is not map[string]interface{}
).
This is a common issue and is covered in the FAQ (this focuses on slices but the same principal applies to maps).
The best approach really depends upon what you are trying to accomplish. You can do something like the following (playground):
package main
import (
"fmt"
)
func main() {
v := make(map[string]interface{})
v["blah"] = 3
test(v)
v["panic"] = "string"
test(v)
}
func test(in map[string]interface{}) {
var ok bool
converted := make(map[string]int)
for k, v := range in {
converted[k], ok = v.(int)
if !ok {
panic("Unexpected type in map")
}
}
fmt.Println(converted)
}
or accept an interface{}
which allows anything to be passed in (playground):
package main
import (
"fmt"
)
func main() {
v := make(map[string]int)
v["blah"] = 3
test(v)
w := make(map[string]string)
w["next"] = "string"
test(w)
x := make(map[string]bool)
x["panic"] = true
test(x)
}
func test(in interface{}) {
switch z := in.(type) {
case map[string]int:
fmt.Printf("dealing with map[string]int: %v\n", z)
case map[string]string:
fmt.Printf("dealing with map[string]string: %v\n", z)
default:
panic(fmt.Sprintf("unsupported type: %T", z))
}
// You could also use reflection here...
}