Golang泛型-简单用例

时间:2018-12-03 03:23:33

标签: 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){
   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之类的属性。

3 个答案:

答案 0 :(得分:3)

您可以通过这种方式使用接口,添加方法class C(A): def __init__(self): super(C, self).__init__() print(self.p1) 以获取每个结构的foo。

print(A().p1)
B('modified')
C()

答案 1 :(得分:2)

由于A,B和C都assignable属于相同的基础类型,因此可以使用带有该基础类型的参数的函数:func handleFoo(v struct{ Foo map[string]string })

Run it on the playground

此方法的局限性在于handleFoo中不提供关于A,B和C的方法(即使具有相同的名称和签名)。

答案 2 :(得分:1)

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

https://play.golang.org/p/sLyjDvVrUjQ

https://golang.org/pkg/reflect/

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
    }
}