Goi*_*Way 3 generics go go-reflect
我有一个命名函数Keys()
来获取地图的所有键,这里是代码:
func main() {
m2 := map[int]interface{}{
2:"string",
3:"int",
}
fmt.Println(Keys(m2))
}
func Keys(m map[interface{}]interface{}) (keys []interface{}) {
for k := range m {
keys = append(keys, k)
}
return keys
}
Run Code Online (Sandbox Code Playgroud)
但是我得到了
cannot use m2 (type map[int]interface {}) as type map[interface {}]interface {} in argument to Keys
Run Code Online (Sandbox Code Playgroud)
Go支持泛型,我该如何修复代码?
小智 6
1- Golang是强类型语言,因此map[int]interface{}
与之不兼容map[interface{}]interface{}
.
int
是不同的类型interface{}
,并看到:Go:接口{}的含义是什么?
2-不,Golang不支持泛型,这非常好,因为它使语言简单快速.
你有一些选择:
如果您不想更改所使用的地图类型:
1-您可以将该功能编辑为:func Keys(m map[int]interface{}) []int
,就像这个工作示例代码:
package main
import "fmt"
func main() {
m2 := map[int]interface{}{
2: "string",
3: "int",
}
fmt.Println(Keys(m2))
}
func Keys(m map[int]interface{}) []int {
keys := make([]int, len(m))
i := 0
for k := range m {
keys[i] = k
i++
}
return keys
}
Run Code Online (Sandbox Code Playgroud)
输出(可能不是按顺序):
[2 3]
Run Code Online (Sandbox Code Playgroud)
2-或者你可以编辑函数:func Keys(m map[int]interface{}) []interface{}
,像这个工作示例代码:
package main
import "fmt"
func main() {
m2 := map[int]interface{}{
2: "string",
3: "int",
}
fmt.Println(Keys(m2))
}
func Keys(m map[int]interface{}) []interface{} {
keys := make([]interface{}, len(m))
i := 0
for k := range m {
keys[i] = k
i++
}
return keys
}
Run Code Online (Sandbox Code Playgroud)
输出(可能不是按顺序):
[2 3]
Run Code Online (Sandbox Code Playgroud)
如果您不想更改使用的Keys
功能:
3-您可以将地图编辑为:map[interface{}]interface{}
,如下工作示例代码:
package main
import "fmt"
func main() {
m2 := map[interface{}]interface{}{
2: "string",
3: "int",
}
fmt.Println(Keys(m2))
}
func Keys(m map[interface{}]interface{}) []interface{} {
keys := make([]interface{}, len(m))
i := 0
for k := range m {
keys[i] = k
i++
}
return keys
}
Run Code Online (Sandbox Code Playgroud)
4-此外,您可以reflect
在某些用例中使用包,但性能(速度)会受到影响.
并参见:反思的法则
除了 Amd 的解决方案,如果您不想更改使用的地图类型,您还可以使用反射库。
func main() {
m2 := map[int]interface{}{
2: "string",
3: "int",
}
k := Keys(m2)
fmt.Printf("Keys: %v\n", k)
}
func Keys(m interface{}) (keys []interface{}) {
v := reflect.ValueOf(m)
if v.Kind() != reflect.Map {
fmt.Errorf("input type not a map: %v", v)
}
for _, k := range v.MapKeys() {
keys = append(keys, k.Interface())
}
return keys
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果您使用此解决方案,则返回的键Keys
将包含包装在接口本身中的每个键值。因此,要获得实际值,您可能必须进行类型断言:
k := Keys(m2)
k1 := k[0].(int) // k[0] is an interface value, k1 is an int
Run Code Online (Sandbox Code Playgroud)
工作代码。