gpt4 book ai didi

dictionary - 如何使用反射来反转 map

转载 作者:行者123 更新时间:2023-12-01 20:08:37 24 4
gpt4 key购买 nike

我正在Go中学习reflect,并尝试实现获取map并返回另一个map的功能,其中键将是值,而值将是键。
例子:

m := map[string]int{"one": 1, "two": 2}
fmt.Println(ReverseMap(m)) // {1: "one", 2: "two"}
这是我的代码:
func ReverseMap(in interface{}) interface{} {

var out reflect.Value
v := reflect.ValueOf(in)
if v.Kind() == reflect.Map {
for idx, key := range v.MapKeys() {
value := v.MapIndex(key)
if idx == 0 {
mapType := reflect.MapOf(reflect.TypeOf(value), reflect.TypeOf(key))
out = reflect.MakeMap(mapType)
}
out.SetMapIndex(value, key)
}
}
return out
}
这段代码 panic错误:

panic: reflect.Value.SetMapIndex: value of type int is not assignable to type reflect.Value


我认为此错误的原因是 out变量的声明,但是如果我不知道此变量的类型,我不知道如何正确声明它。
如何解决此错误?

最佳答案

keyvalue的类型为 reflect.Value ,因此将它们传递给 reflect.TypeOf() 不会返回映射键和值类型(stringint)的类型描述符,而是reflect.Value类型本身的类型描述符。
相反,只需调用其 Value.Type() 方法:

mapType := reflect.MapOf(value.Type(), key.Type())
这样,它将(几乎)工作并打印(在 Go Playground上尝试):
map[1:one 2:two]
我写“几乎”是因为您返回的是 reflect.Value,而不是 map。但是,如果将 reflect.Value传递给 fmt 软件包,它将打印包装在其中的值:

If the operand is a reflect.Value, the operand is replaced by the concrete value that it holds, and printing continues with the next rule.


因此,在返回之前,应在 Value.Interface()上调用 out
如果种类不是 map ,则提早返回比较容易,因此您可以在此之后立即创建 map :
func ReverseMap(in interface{}) interface{} {
v := reflect.ValueOf(in)
if v.Kind() != reflect.Map {
return nil
}

mapType := reflect.MapOf(v.Type().Elem(), v.Type().Key())
out := reflect.MakeMap(mapType)

for _, key := range v.MapKeys() {
out.SetMapIndex(v.MapIndex(key), key)
}

return out.Interface()
}
Go Playground上尝试此变体。
另一种方法可能是使用 Value.MapRange() :
for iter := v.MapRange(); iter.Next(); {
out.SetMapIndex(iter.Value(), iter.Key())
}
Go Playground上尝试此变体。

关于dictionary - 如何使用反射来反转 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62692558/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com