在Golang中使用泛型從任何map中獲取鍵的slice

banq發表於2022-03-17

在Go 1.18之前,當你想從Go中的map中提取一個鍵列表時,你必須編寫程式碼來迭代map並將鍵新增到一個slice中。

從1.18起,有了新的泛型功能,你可以寫一個單一的通用函式,從任何map中獲取鍵,並在需要時使用它。不用再為特定型別的map編寫程式碼了。

伴隨著Go 1.18的釋出,golang.org/x/exp/maps包也已經發布,Keys()函式的工作原理與下面的相同。

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作為引數,其中的鍵是具有可比較約束的型別,而值則具有any約束。

comparable約束描述了其值可以被比較的型別,這意味著==和!=運算子可以在它們身上使用。

any約束等同於interface{}:它接受任何型別,所以map的值可以是任何東西。

該函式的其餘部分非常簡單。它返回一個[]K的鍵slice,所以在函式主體的第一行,建立了所產生的slice。

注意,它的容量等於map的大小。然後,在一個迴圈中,每個map的鍵都被新增到生成的slice中。

用兩個不同的map執行示例程式碼,你會得到這樣的輸出。

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

這就是全部。現在,通過一個keys()函式,你可以得到任何map的keys列表。

 

相關文章