It's true that interface{}
is kind of like C's void *
, but you can't implicitly convert a map[string]string
into a map[string]interface{}
. The key is to define your map
objects at their declaration as map[string]interface{}
objects. Unfortunately, you cannot assign new values to such a map, since Go can't know how much memory to allocate for each instance.
func main() {
one := map[string]interface{} {
"A": []string{"a", "b", "c"},
}
fmt.Println(map_exist(one, "A"))
two := map[string]interface{} {
"B": "a",
}
fmt.Println(map_exist(two, "B"))
}
This works, but it probably isn't useful enough for your intended use case.
Another approach is to define a generic map interface and make sure that the functions you intend to use are defined for the types you want to support. Basically, your goal is to build a library that's useful enough that you can reasonably offload the work of implementing your interface to the library's users. It would be nice if you could declare a default function or maybe just a macro to prevent the copy-paste, but I'm not aware of such a mechanism.
Here's an example using an interface:
type GenericMap interface{
ValueForKey(string) (interface{}, bool)
}
type SliceMap map[string][]string
type StringMap map[string]string
type VoidMap map[string]interface{}
func map_exist(map_val GenericMap, key string) bool {
_, ok := map_val.ValueForKey(key)
return ok
}
func (map_val SliceMap) ValueForKey(key string) (interface{}, bool) {
val, ok := map_val[key]
return val, ok
}
func (map_val StringMap) ValueForKey(key string) (interface{}, bool) {
val, ok := map_val[key]
return val, ok
}
func (map_val VoidMap) ValueForKey(key string) (interface{}, bool) {
val, ok := map_val[key]
return val, ok
}
func main() {
one := SliceMap {
"A": []string{"a", "b", "c"},
}
fmt.Println(map_exist(GenericMap(one), "A"))
two := StringMap {
"B": "a",
}
fmt.Println(map_exist(GenericMap(two), "B"))
}
In the end, Go programmers tend to prefer a simple, straight-forward solution over all this misdirection, so your best bet is to just use the construct proposed by @Logiraptor:
if _, ok := m[key]; ok {
// You're ok!
}