使用Go中的泛型函数从map中获取一个键的片断的方法

109 阅读1分钟

在Go 1.18之前,当你想从Go中的地图中提取一个键列表时,你必须编写代码来迭代地图并将键添加到一个片断中。从那时起,有了新的泛型功能,你可以写一个单一的通用函数,从任何地图中获取键,并在需要时使用它。不再为特定类型的地图编写代码😉。

package main

import (
    "fmt"
)

func keys[K comparable, V any](m map[K]V) []K {
    keys := make([]K, 0, len(m))
    for k := range m {
        keys = append(keys, k)
    }
    return keys
}

func main() {
    vegetableSet := map[string]bool{
        "potato":  true,
        "cabbage": true,
        "carrot":  true,
    }

    fruitRank := map[int]string{
        1: "strawberry",
        2: "raspberry",
        3: "blueberry",
    }

    fmt.Printf("vegetableSet keys: %+v\n", keys(vegetableSet))
    fmt.Printf("fruitRank keys: %+v\n", keys(fruitRank))
}

keys() 函数接收一个map作为参数,其中键的类型为带 comparable约束,而值则是带有 any约束。正如你可能已经从我们之前的泛型教程中知道的, comparable约束描述的是值可以被比较的类型,这意味着可以对它们使用==!= 操作符。该 any约束等同于interface{} - 它接受任何类型,所以map的值可以是任何东西。

该函数的其余部分非常简单。它返回一个键的片断[]K ,所以在函数主体的第一行,创建了所产生的片断。注意,它的容量等于地图的大小。然后,在一个循环中,每个地图键被添加到所产生的片断中。用两个不同的地图运行示例代码,你会得到输出:

vegetableSet keys: [potato cabbage carrot]
fruitRank keys: [1 2 3]

这就是全部。现在,只需一个keys() 函数,你就可以得到任何map的键的列表。