猿问

Golang 泛型 - 简单用例

假设我有 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 这样的属性。


人到中年有点甜
浏览 109回答 3
3回答

侃侃尔雅

您可以以这种方式使用接口,添加一个方法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"]}

拉风的咖菲猫

因为 A、B 和 C 都可分配给相同的底层类型,所以您可以使用带有该底层类型参数的函数:func handleFoo(v struct{ Foo map[string]string })在操场上运行它。这种方法的一个限制是 A、B 和 C 上的方法(即使具有相同的名称和签名)在handleFoo.

拉丁的传说

你可以尝试reflect传递interface{}给handleFoohttps://play.golang.org/p/sLyjDvVrUjQhttps://golang.org/pkg/reflect/package mainimport (    "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    }}
随时随地看视频慕课网APP

相关分类

Go
我要回答