我写了一个函数,它将从map [string] Foo返回一个排序的字符串切片。我很好奇创建一个通用例程的最佳方法是什么,该例程可以从任何类型返回一个排序的字符串切片,该类型是一个以字符串作为键的映射。
有没有办法使用接口规范?例如,有没有办法做类似的事情:
type MapWithStringKey interface {
<some code here>
}
要实现上面的接口,类型需要字符串作为键。然后我可以编写一个泛型函数,它返回一个用于完成类型的键的排序列表。
这是我目前使用反射模块的最佳解决方案:
func SortedKeys(mapWithStringKey interface{}) []string {
keys := []string{}
typ := reflect.TypeOf(mapWithStringKey)
if typ.Kind() == reflect.Map && typ.Key().Kind() == reflect.String {
switch typ.Elem().Kind() {
case reflect.Int:
for key, _ := range mapWithStringKey.(map[string]int) {
keys = append(keys, key)
}
case reflect.String:
for key, _ := range mapWithStringKey.(map[string]string) {
keys = append(keys, key)
}
// ... add more cases as needed
default:
log.Fatalf("Error: SortedKeys() does not handle %s\n", typ)
}
sort.Strings(keys)
} else {
log.Fatalln("Error: parameter to SortedKeys() not map[string]...")
}
return keys
}
Click for Go Playground version
我被迫为每个支持的类型编写类型断言,即使在编译时,我们应该知道mapWithStringKey参数的确切类型。
答案 0 :(得分:5)
您无法制作部分类型。但您可以定义一个符合您目的的界面:
type SortableKeysValue interface {
// a function that returns the strings to be sorted
Keys() []string
}
func SortedKeys(s SortableKeysValue) []string {
keys := s.Keys()
sort.Strings(keys)
return keys
}
type MyMap map[string]string
func (s MyMap) Keys() []string {
keys := make([]string, 0, len(s))
for k, _ := range s {
keys = append(keys, k)
}
return keys
}
答案 1 :(得分:0)
希望有所帮助(go-1.1):
package main
import (
"fmt"
"reflect"
)
var m = map[string]int{"a": 3, "b": 4}
func MapKeys(m interface{}) (keys []string) {
v := reflect.ValueOf(m)
for _, k := range v.MapKeys() {
keys = append(keys, k.Interface().(string))
}
return
}
func main() {
fmt.Printf("%#v\n", MapKeys(m))
}