通用地图值

时间:2014-09-10 18:16:54

标签: go hashmap

当我想以类似的方式使用地图的键但是地图中的值不同时,我遇到过这个问题几次。我以为我可以编写一个函数,它接受我想要的键类型接口{}作为值类型,但它不起作用。

func main() {
    mapOne := map[string]int
    mapTwo := map[string]double
    mapThree := map[string]SomeStruct

    useKeys(mapOne)
}
func useKeys(m map[string]interface{}) {
    //something with keys here
}

不确定是否有一种优雅的方式来做到这一点我只是感觉腰部完全重写了不同价值的简单事物。

2 个答案:

答案 0 :(得分:13)

虽然go中的map和slice本身是通用的,但它们不是协变的(也不是,因为接口不是泛型)。使用一种没有泛型的语言,你将不得不重复一些事情。

如果您真的需要获取任何旧地图的键,您可以使用反射来执行此操作:

func useKeys(m interface{}) {
    v := reflect.ValueOf(m)
    if v.Kind() != reflect.Map {
        fmt.Println("not a map!")
        return
    }

    keys := v.MapKeys()
    fmt.Println(keys)
}

答案 1 :(得分:0)

从 Go 1.18 开始,您将能够为此编写一个 type parametrized (又名泛型)函数:

func main() {
    m1 := map[string]int{"foo": 1}
    m2 := map[string]float64{"foo": 4.5}
    m3 := map[string]*SomeStruct{}

    fmt.Println(useKeys(m1))
    fmt.Println(useKeys(m2))
    fmt.Println(useKeys(m3))

}

func useKeys[V any](m map[string]V) V {
    return m["foo"]
}

如您所见,类型参数 V 与映射值统一,因此您可以明确强制 useKeys 的调用者传递键为 string 的映射。

您可以在 Go2 Playground 上现场观看:https://go2goplay.golang.org/p/epFA2_9u5l5