获取不同内容地图的所有地图键[string]

问题描述 投票:0回答:2

我有一个足够通用的函数来遍历地图[字符串]并获取所有键:

i := 0
keys := make([]string, len(input))
for k := range input {
    keys[i] = k
    i++
}
return keys

我的问题是我想在这里放入两个不同的输入,一个 map[string]MyStructmap[string][][]float64。每当我尝试将 func 的输入作为 map[string]interface{} 时,go 都会抵制我尝试将 map[string]MyStruct 转换为 map[string]interface{} 的所有尝试。有没有一种方法可以做到这一点,而不需要有两个函数,一个使用map[string]MyStruct作为输入,另一个使用map[string][][]float64?此时,map[string] 的内容并不重要,因为我只是想获取它们的所有键以供稍后在代码中使用。这需要是一个被调用的函数;我们正在使用 Sonar,它被设置为拒绝代码重复,所以我不能重复此代码片段。

function dictionary go
2个回答
3
投票

在下一个 Go 版本为我们带来泛型之前,有多种方法可以应对它。

  1. 重复代码

  2. 使用代码生成 - 设计一些模板,然后继续构建将为您填充它。

  3. 使用

    interface{}
    作为函数的输入类型,然后使用反射来猜测函数的类型。 我很确定在这种情况下通用代码将比 2 个独立的函数更复杂。

func getKeys(input interface{}) []string {
    switch inp := input.(type) {
    case map[string]MyStruct:
        keys := make([]string, 0, len(inp))
        for k := range inp {
            keys = append(keys, k)
        }
        return keys
    case map[string][]float64:
        ...
    default:
        fmt.Printf("I don't know about type %T!\n", v)
}

您不能使用输入类型

map[string]interface{}
来放置
map[string]string
map[string][]string
go 不会将每个值复制到新类型。您可以采用最通用的类型
interface{}
然后投射它。


0
投票

现在 Go 有了

generics
这可以进一步简化:

func getKeys[T any](input map[string]T) []string {
    keys := make([]string, 0, len(input))
    for k := range input {
        keys = append(keys, k)
    }
    return keys
}

var intMap = map[string]int{"one": 1, "two": 2, "three": 3}
var stringMap = map[string]string{"one": "1", "two": "2", "three": "3"}
var floatMap = map[string]float64{"one": 1.0, "two": 2.0, "three": 3.0}

func main() {
    fmt.Println(getKeys(intMap))
    fmt.Println(getKeys(stringMap))
    fmt.Println(getKeys(floatMap))
}
© www.soinside.com 2019 - 2024. All rights reserved.