Interface Go是否允许为具有特定键类型的映射指定接口?

Interface Go是否允许为具有特定键类型的映射指定接口?,interface,go,Interface,Go,我编写了一个函数,该函数将从map[string]Foo返回字符串的排序片段。我很好奇,创建一个通用例程的最佳方法是什么,该例程可以从任何类型返回字符串的排序片段,该类型是以字符串作为键的映射 有没有一种使用接口规范的方法?例如,是否有任何方法可以执行以下操作: type MapWithStringKey interface { <some code here> } 我被迫为每个支持的类型编写类型断言代码,即使在编译时,我们应该知道mapWithStringKey参数的确

我编写了一个函数,该函数将从map[string]Foo返回字符串的排序片段。我很好奇,创建一个通用例程的最佳方法是什么,该例程可以从任何类型返回字符串的排序片段,该类型是以字符串作为键的映射

有没有一种使用接口规范的方法?例如,是否有任何方法可以执行以下操作:

type MapWithStringKey interface {
    <some code here>
}


我被迫为每个支持的类型编写类型断言代码,即使在编译时,我们应该知道mapWithStringKey参数的确切类型。

您不能创建部分类型。但您可以定义一个符合您的目的的接口:

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
}
请在此处尝试:

希望有帮助(go-1.1):


恐怕你需要仿制药。众所周知,Go语言中不包括泛型。尽管如此,使用泛型能够真正简化问题的案例并不多:它们通常会增加更多的层次和复杂性。我担心。。。哦,你的解决方案并没有解决真正的问题:对于每一种以字符串作为键的不同类型,你都必须编写另一个keys()func。使用reflect可以得到一个更简单的解决方案,它还需要对每种类型进行修改:我收回上面的评论。我认为您的解决方案比基于反射的解决方案更好,即使它有点冗长。需要Keys()方法将允许编译时检查,并且添加的方法可以位于类型代码的旁边。此外,编译器正在优化(内联)这段代码,这是它无法为单函数解决方案所做的。当字符串映射作为数据结构有点幼稚时,这种方法也可以很好地伸缩。
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
}
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))
}