Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 函数,它接受映射并只关心键类型_Go - Fatal编程技术网

Go 函数,它接受映射并只关心键类型

Go 函数,它接受映射并只关心键类型,go,Go,我有两个映射,它们都由字符串设置键,但是值是两种不同的自定义类型 map[string]type1 map[string]type2 现在我想写一个函数,它可以接受这两种类型中的任何一种,因为这个函数只看键,根本不关心值。所以我认为应该是这样的: func takeTheMap(argument map[string]interface{}) { ... 但这不起作用,因为: cannot use myVariable (type map[string]customType) as type

我有两个映射,它们都由
字符串设置键,但是值是两种不同的自定义类型

map[string]type1
map[string]type2
现在我想写一个函数,它可以接受这两种类型中的任何一种,因为这个函数只看键,根本不关心值。所以我认为应该是这样的:

func takeTheMap(argument map[string]interface{}) {
...
但这不起作用,因为:

cannot use myVariable (type map[string]customType) as type map[string]interface {} in argument to takeTheMap


我能设法做到吗

Go中唯一的多态性是接口。唯一的替代方案是反射、复制或重新思考更广泛的设计,这样您就不需要做您在这里试图做的事情

如果最后一个选项不可行,我个人建议复制,因为这是一整四行代码

keys := make([]string, 0, len(myMap))
for key,_ := range myMap {
    keys = append(keys,key)
}

一个大而复杂的泛型助手似乎是不必要的。

Go中唯一的多态性是接口。唯一的替代方案是反射、复制或重新思考更广泛的设计,这样您就不需要做您在这里试图做的事情

如果最后一个选项不可行,我个人建议复制,因为这是一整四行代码

keys := make([]string, 0, len(myMap))
for key,_ := range myMap {
    keys = append(keys,key)
}

一个大而复杂的通用助手似乎有点多余。

一个使用接口的解决方案。这个例子似乎有点过头了,在你的例子中(我不确定,在你的例子中没有足够的细节)最好只使用几个
循环

package main

import (
    "fmt"
)

type foo bool
type bar string

type mapOne map[string]foo
type mapTwo map[string]bar

func (m mapOne) Keys() []string {
    s := []string{}
    for k := range m {
        s = append(s, k)
    }
    return s
}

func (m mapTwo) Keys() []string {
    s := []string{}
    for k := range m {
        s = append(s, k)
    }
    return s
}

type ToKeys interface {
    Keys() []string
}

func main() {
    m1 := mapOne{"one": true, "two": false}
    m2 := mapTwo{"three": "foo", "four": "bar"}

    doSomething(m1)
    doSomething(m2)
}

func doSomething(m ToKeys) {
    fmt.Println(m.Keys())
}

操场

使用接口的解决方案。这个例子似乎有点过头了,在你的例子中(我不确定,在你的例子中没有足够的细节)最好只使用几个
循环

package main

import (
    "fmt"
)

type foo bool
type bar string

type mapOne map[string]foo
type mapTwo map[string]bar

func (m mapOne) Keys() []string {
    s := []string{}
    for k := range m {
        s = append(s, k)
    }
    return s
}

func (m mapTwo) Keys() []string {
    s := []string{}
    for k := range m {
        s = append(s, k)
    }
    return s
}

type ToKeys interface {
    Keys() []string
}

func main() {
    m1 := mapOne{"one": true, "two": false}
    m2 := mapTwo{"three": "foo", "four": "bar"}

    doSomething(m1)
    doSomething(m2)
}

func doSomething(m ToKeys) {
    fmt.Println(m.Keys())
}

操场

如果你能说明你的用例是什么,以及为什么你需要这样的简陋的东西,那会有帮助的?我可以想出另一个适合你的解决方案,但由于它也涉及到空界面,它甚至比你现有的更粗糙。使用
Get(k string)interface{}
创建一个接口,然后声明两个自定义映射类型并让它们实现该接口。B.使用空接口(
interface{}
)作为函数的参数,并让函数使用反射来检索提供的映射值。@Havelock我正在处理一个需要在内存中保存多种类型索引的服务,这些嵌套映射是不同的索引类型。但是有些方法需要在两种索引类型上执行相同的操作,这就是为什么我希望它们是泛型的。如果你能说明你的用例是什么,以及你为什么需要这样粗糙的东西,这会有所帮助?我可以想出另一个适合你的解决方案,但由于它也涉及到空界面,它甚至比你现有的更粗糙。使用
Get(k string)interface{}
创建一个接口,然后声明两个自定义映射类型并让它们实现该接口。B.使用空接口(
interface{}
)作为函数的参数,并让函数使用反射来检索提供的映射值。@Havelock我正在处理一个需要在内存中保存多种类型索引的服务,这些嵌套映射是不同的索引类型。但是有些方法需要对这两种索引类型执行相同的操作,这就是为什么我希望它们是泛型的。