我正在尝试创建一个辅助函数,它将使用字符串键获取一个映射并返回一个映射键片段。
问题在于我希望函数不关心地图值的类型。
例如:
stringStringMap := map[string]string{
"one": "first",
"two": "second"
}
mapKeys(stringStringMap) // ["one", "two"]
stringIntMap := map[string]int{
"one": 1,
"two": 2,
}
mapKeys(strinIntMap) // ["one", "two"]
似乎解决这个问题的唯一方法是创建两个类似的帮助器。像这样:
func mapKeys(m map[string]string) []string {
...
}
func mapKeys2(m map[string]int) []string {
...
}
但这看起来很难看。我正在尝试创建这个辅助函数吗?如果没有,那么写这个时我应该遵循一个很好的约定吗?
答案 0 :(得分:3)
解决此问题的方法是使用" interface {}"在创建地图时,然后在方法中使用type switch语句,即
func mapKeys(m map[string]interface{}) []string {
for k,v := range m {
switch a := v.(type) {
case int:
... do int stuff
case string:
... do string stuff
}
}
}
答案 1 :(得分:2)
Go没有用户指定的通用参数类型,因此您所描述的内容必须通过以下方式完成:
require
)并使用reflection。以下是第二种方法的示例实现:
interface{}
答案 2 :(得分:2)
还有第三个选项尚未提及,那就是使用类型开关。如果您知道要将可管理数量的类型传递给函数,这可能是一个不错的选择。它会像这样工作:
func Keys(m interface{}) ([]string, error) {
switch t := m.(type) {
case map[string]string:
keys := make([]string, 0, len(t))
for key := range t {
keys = append(keys, key)
}
return keys, nil
case map[string]int:
keys := make([]string, 0, len(t))
for key := range t {
keys = append(keys, key)
}
return keys, nil
default:
return nil, fmt.Errorf("unknown map type: %T", m)
}
}
这仍然会给你一堆看似重复的代码,但至少它只是在一个函数名后面,而且它比反射更有效。