Go:一个使用不同类型值的映射的函数
在我的代码中,我需要一个函数,该函数将从映射返回键的有序切片Go:一个使用不同类型值的映射的函数,go,Go,在我的代码中,我需要一个函数,该函数将从映射返回键的有序切片 m1 := make(map[string]string) m2 := make(map[string]int) 现在我需要调用一个传递两种类型映射的函数: keys1 := sortedKeys(m1) keys2 := sortedKeys(m1) 问题:我必须编写两个函数,因为该函数应该使用两种不同类型的映射。同时,函数体在两种情况下都是相同的 问题:如何对两个映射使用单个实现?或者有没有其他优雅的方法来解决这个问题 我的第
m1 := make(map[string]string)
m2 := make(map[string]int)
现在我需要调用一个传递两种类型映射的函数:
keys1 := sortedKeys(m1)
keys2 := sortedKeys(m1)
问题:我必须编写两个函数,因为该函数应该使用两种不同类型的映射。同时,函数体在两种情况下都是相同的
问题:如何对两个映射使用单个实现?或者有没有其他优雅的方法来解决这个问题
我的第一个想法是使用map[string]interface{}
作为参数类型,但不能将map[string]string
或map[string]int
分配给它
我的代码:
func sortedKeys(m map[string]string) []string {
var keys []string
for key := range m {
keys = append(keys, key)
}
sort.Strings(keys)
return keys
}
我必须重复相同的代码,但是对于
map[string]int
您可以使用接口{}和反射来实现这一点
您可以为同一个函数编写两个函数,但它是不可伸缩的,例如,您现在支持字符串和int,但希望将来支持int64、float64、bool或struct。使用map[string]接口{}和反射实现一个公共函数是一个不错的选择
建议代码:
package main
import (
"fmt"
"reflect"
)
func main() {
m1 := make(map[string]string)
m2 := make(map[string]int)
m1["a"] = "b"
m1["b"] = "c"
m2["a"] = 1
m2["b"] = 2
fmt.Println(sortedKeys(m1))
fmt.Println(sortedKeys(m2))
}
// Returns slice of values in the type which is sent to it
func sortedKeys(m interface{}) interface{} {
if m == nil {
return nil
}
if reflect.TypeOf(m).Kind() != reflect.Map {
return nil
}
mapIter := reflect.ValueOf(m).MapRange()
mapVal := reflect.ValueOf(m).Interface()
typ := reflect.TypeOf(mapVal).Elem()
outputSlice := reflect.MakeSlice(reflect.SliceOf(typ), 0, 0)
for mapIter.Next() {
outputSlice = reflect.Append(outputSlice, mapIter.Value())
}
return outputSlice.Interface()
}
输出:
[丙]
[12]
编写两个函数。其实很简单。您甚至可以编写三个函数。在开始第四版之前:考虑切换到反射。@ SashaShpota也许会很棒,但这是不可能的。本质上,您似乎在问是否可以只指定“类型的一半”,例如
map[string]
,或map[string]
,然后编写一个接受此类类型的函数,然后能够向其传递类型值,如map[string]string
和map[string]int
。在Go中,这根本不可能,要么编写两个函数,要么使用接口{}
和反射。@mkopriva谢谢!“不可能”也是一个有效的答案:)我问这个问题是因为我在围棋方面没有经验,正在寻找更好的解决方案。“但仍然是8行代码”。那是个笑话,对吗?8行琐碎的代码实际上什么都不是。只需写两次就可以了。这在Go中是不可能的,因为Go不支持泛型。重复8行代码被认为是可以接受的。@shasha Spota:你能告诉我这个解决方案是否对你有效吗?如果是,你能接受这一正确答案吗。非常感谢。