我想创建一个泛型方法,以数组的形式从映射中提取键--这样数组的类型就应该与映射中键的类型相同.我知道我希望用法是这样的:

mapWithStringKeys := map[string]string {
    "one": "1",
    "ten": "10",
    "hundred": "100",
}

mapWithIntKeys := map[int]string {
    1: "one",
    10: "ten",
    100: "hundred",
}


keys(mapWithStringKeys) // []string{"one", "ten", "hundred"}
keys(mapWithStringKeys) // []int{1, 10, 100}

提取密钥的内部逻辑如下所示:

keys := make([]<TYPE>, 0, len(mymap))
for k := range mymap {
    keys = append(keys, k)
}

我在定义函数时遇到了很多问题,这样Golang就知道如何"传递"类型.我的想象是这样的:

func keys[T infer](m map[T]any) []T {
    keysArr := make([]T, 0, len(mymap))
    for k := range mymap {
        keysArr = append(keysArr, k)
    }
    return keysArr
}

但我真的搞不清楚,所以我想知道这是否可能,如果不可能,为什么?

推荐答案

你差一点就成功了.将键类型声明为可比较的,并对值类型使用类型约束.

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

要处理命名的映射类型,请使用~来包含映射类型的约束.

func keys[M ~map[T]V, T comparable, V any](mymap M) []T {
    keysArr := make([]T, 0, len(mymap))
    for k := range mymap {
        keysArr = append(keysArr, k)
    }
    return keysArr
}

H/T感谢Burak指出了existing library function.

Go相关问答推荐

ChromeDriver不存在(高朗selenium)

在不耗尽资源的情况下处理S3文件下载

Golang XML密钥名称冲突

需要类型[]*structpb.Value(GCP Golang客户端库;aiPlatform)

Wamtime Memory中的‘Offset’是什么?Read?

如何使用中间件更改http请求的响应代码?

优化方式中所有可能组合的字符串相似度

Go安装成功但没有输出简单的Hello World

Golang telegram 机器人

在 GoLang 中对自定义 struct 体数组进行排序

如何使用gosdk在Dynamodb中进行UpdateItem时,将ValueBuilder对象声明为StringSet类型?

你如何在 Golang 代码中测试 filepath.Abs​​ 失败?

是否可以从 golang 中的参数推断类型?

Get 请求在 Thunder 客户端/Postman 中返回数据,但在 Golang 代码中给出空白数据

如何使用 Docker 引擎 SDK 和 Golang 运行 docker 挂载卷

如何使用 go-playground/validator 编写 snake case 绑定标签?

在恒等函数中将类型 T 转换为类型 U

每次有人进入我的网站时如何运行特定功能?

如何在Go中替换符号并使下一个字母大写

Unescape 在 rss 中两次逃脱了标题