Golang泛型-简单用例

Golang泛型-简单用例,go,Go,假设我有3个结构: type A struct{ Foo map[string]string } type B struct{ Foo map[string]string } type C struct{ Foo map[string]string } 然后我想创建一个可以接受任何结构的函数: func handleFoo (){ } 有什么办法可以让Golang这样做吗?比如: type ABC = A | B | C func handleFoo(v ABC){

假设我有3个结构:

type A struct{
   Foo map[string]string
}

type B struct{
   Foo map[string]string
}

type C struct{
   Foo map[string]string
}
然后我想创建一个可以接受任何结构的函数:

func handleFoo (){

}
有什么办法可以让Golang这样做吗?比如:

type ABC = A | B | C

func handleFoo(v ABC){
   x: = v.Foo["barbie"] // this would be nice!
}
好的,让我们尝试一个界面:

type FML interface {
  Bar() string
}

func handleFoo(v FML){
   z := v.Bar() // this will compile
   x: = v.Foo["barbie"] // this won't compile - can't access properties like Foo from v
}

在一种鼓励/强制组合的语言中,我无法理解为什么不能访问像Foo这样的属性。

因为a、B和C都属于相同的底层类型,所以可以使用具有该底层类型参数的函数:
func handleFoo(v struct{Foo map[string]string})


这种方法的一个限制是A、B和C上的方法(即使具有相同的名称和签名)在
handleFoo
中不可用

您可以这样使用接口,添加一个方法
GetFoo
来获取每个结构的foo

type A struct{
    Foo map[string]string
}

func(a *A) GetFoo() map[string]string {
    return a.Foo
}

type B struct{
    Foo map[string]string
}

func(b *B) GetFoo() map[string]string {
    return b.Foo
}

type C struct{
    Foo map[string]string
}

func(c *C) GetFoo() map[string]string {
    return c.Foo
}

type ABC interface {
    GetFoo() map[string][string]
}

func handleFoo (v ABC){
    foo := v.GetFoo()
    x:=foo["barbie"]
}

您可以尝试
reflect
并将
接口{}
传递给
handleFoo


从技术上讲,我不认为这是泛型,它与类型层次结构或接口有关。在其他任何情况下,当你告诉自己“我需要泛型”时,准备像疯子一样复制粘贴问题中显示的类型和
handleFoo
,或者代码生成,实际上是同样可怕的解决方案,您可以使用
func-handleFoo(v-struct{Foo-map[string]string})
。这种方法有局限性。例如,
handleFoo
无法访问类型A、B或C中的任何方法。Go没有泛型。试图假装这是一个愚蠢的想法。代码的目标是什么?让我们关注您的问题,而不是您不支持的解决方案。事实上,这是一个挑战。接受不同的类型很容易。这就是接口的用途。是的,这只适用于所有3个结构都具有完全相同的类型的情况,但除非出现更好的情况,否则我很快就会接受这个答案,就像我说的,从技术上说,我不认为这是泛型,但你会称之为什么语言特性?类型必须可分配给相同的底层类型。这些类型可以不同,如问题中所示,如链接的游乐场示例所示。规范中关于可分配性的部分是。A、B和C是不同的类型,但它们具有相同的基础类型。Go不允许将
A
分配给
B
,但是
A
B
都可以分配给
struct{Foo map[string]string}
语言特性是可分配的。是的,这是有效的,因为它们基本上是相同的。准确的类型。lol..回答得很好。如果一个是
map[string]string
,另一个是
map[string]int
,另一个是
map[string]bool
,它会工作吗?我不认为这些值是不同的类型。接口应更改为
GetFoo()map[string]接口
@AlexanderMills在您自己的问题示例代码中,它们的类型完全相同。如果你需要一些不同的东西,编辑问题以澄清这一点。
package main

import (
    "fmt"
    "reflect"
)

func main() {
    type A struct {
        Foo map[string]string
    }
    type B struct {
        Foo map[string]int
    }
    type C struct {
        Foo map[string]uint
    }
    a := A{
        Foo: map[string]string{"a":"1"},
    }

    b := B{
        Foo: map[string]int{"a":2},
    }

    c := C {
        Foo: map[string]uint{"a":3},
    }


    fmt.Println(a, b, c)

    handleFoo(a)
    handleFoo(b)
    handleFoo(c)

    fmt.Println(a, b, c)
}



func handleFoo(s interface{}) {
    v := reflect.ValueOf(s)
    foo := v.FieldByName("Foo")
    if !foo.IsValid(){
        fmt.Println("not valid")
        return
    }

    switch foo.Type() {
    case reflect.TypeOf(map[string]string{}):
        fmt.Println("is a map[string]string")
        foo.Interface().(map[string]string)["a"] = "100"
    case reflect.TypeOf(map[string]int{}):
        fmt.Println("is a map[string]int")
        foo.Interface().(map[string]int)["a"] =  200
    case reflect.TypeOf(map[string]uint{}):
        fmt.Println("is a map[string]uint")
        foo.Interface().(map[string]uint)["a"] =  300
    }
}