Generics 如何获取地图的关键点
我有一个名为Generics 如何获取地图的关键点,generics,go,go-reflect,Generics,Go,Go Reflect,我有一个名为Keys() func main(){ m2:=映射[int]接口{}{ 2:“字符串”, 3:“int”, } 格式打印LN(图例(m2)) } func键(m映射[接口{}]接口{})(键[]接口{}){ 对于k:=范围m{ keys=追加(keys,k) } 返回键 } 但是我有 cannot use m2 (type map[int]interface {}) as type map[interface {}]interface {} in argument to Keys
Keys()
func main(){
m2:=映射[int]接口{}{
2:“字符串”,
3:“int”,
}
格式打印LN(图例(m2))
}
func键(m映射[接口{}]接口{})(键[]接口{}){
对于k:=范围m{
keys=追加(keys,k)
}
返回键
}
但是我有
cannot use m2 (type map[int]interface {}) as type map[interface {}]interface {} in argument to Keys
Go是否支持泛型以及如何修复代码?1-Golang是强类型语言,因此map[int]接口{}
与map[interface{}]接口{}
不兼容
int
与接口{}
的类型不同,
请参阅:
2-不,Golang不支持泛型,这非常好,因为它使语言简单快速
您有一些选择:
如果不想更改使用的贴图类型:
1-您可以将函数编辑为:func键(m map[int]interface{})[]int
,如下工作示例代码:
主程序包
输入“fmt”
func main(){
m2:=映射[int]接口{}{
2:“字符串”,
3:“int”,
}
格式打印LN(图例(m2))
}
func键(m映射[int]接口{})[]int{
键:=make([]int,len(m))
i:=0
对于k:=范围m{
键[i]=k
我++
}
返回键
}
输出(可能不符合顺序):
2-或者您可以将函数编辑为:func键(m map[int]interface{})[]interface{}
,如下工作示例代码:
主程序包
输入“fmt”
func main(){
m2:=map[int]接口{}{
2:“字符串”,
3:“int”,
}
格式打印LN(图例(m2))
}
func键(m映射[int]接口{})[]接口{}{
键:=make([]接口{},len(m))
i:=0
对于k:=范围m{
键[i]=k
我++
}
返回键
}
输出(可能不符合顺序):
如果您不想更改所使用的键
功能:
3-您可以将映射编辑为:map[interface{}]interface{}
,如下工作示例代码:
主程序包
输入“fmt”
func main(){
m2:=映射[接口{}]接口{}{
2:“字符串”,
3:“int”,
}
格式打印LN(图例(m2))
}
func键(m映射[接口{}]接口{}][]接口{}{
键:=make([]接口{},len(m))
i:=0
对于k:=范围m{
键[i]=k
我++
}
返回键
}
4-对于某些用例,您也可以使用reflect
包,但会带来性能(速度)损失。
请参阅:除了Amd的解决方案之外,如果您不想更改使用的地图类型,还可以使用reflect库
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
}
请注意,如果使用此解决方案,则从keys
返回的键将包含包装在接口本身中的每个键值。因此,要获得实际值,您可能必须执行类型断言:
k := Keys(m2)
k1 := k[0].(int) // k[0] is an interface value, k1 is an int
.从Go 1.18开始(2022年初,除非延迟),该语言最终将实现类型参数,您将能够轻松编写如下函数:
package main
import (
"fmt"
"reflect"
)
func main() {
m2 := map[int]interface{}{
2: "string",
3: "int",
}
keys := Keys(m2)
fmt.Println(keys) // [2 3]
fmt.Println(reflect.TypeOf(keys)) // []int
}
func Keys[K comparable](m map[K]interface{}) (keys []K) {
for k := range m {
keys = append(keys, k)
}
return keys
}
请注意,基于,类型参数K
上的类型约束是预先声明的标识符compariable
1,而不是any
这是因为地图键必须支持:
比较运算符==
和=必须为键类型的操作数完全定义代码>
因此,您必须仅将K
限制为可比较的类型
1:仍在讨论引入哪些预先声明的标识符;类型参数实现完成后返回检查map[interface{}]interface{}和map[int]interface{}是不同的类型,这就是为什么会出现错误。也许您可以将m2更改为类型map[interface{}]interface{}
k := Keys(m2)
k1 := k[0].(int) // k[0] is an interface value, k1 is an int
package main
import (
"fmt"
"reflect"
)
func main() {
m2 := map[int]interface{}{
2: "string",
3: "int",
}
keys := Keys(m2)
fmt.Println(keys) // [2 3]
fmt.Println(reflect.TypeOf(keys)) // []int
}
func Keys[K comparable](m map[K]interface{}) (keys []K) {
for k := range m {
keys = append(keys, k)
}
return keys
}