为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 泛型 - 简单用例

Golang 泛型 - 简单用例

Go
人到中年有点甜 2023-05-15 10:36:22
假设我有 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 | Cfunc 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 回答

?
侃侃尔雅

TA贡献1801条经验 获得超15个赞

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

}


查看完整回答
反对 回复 2023-05-15
?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

因为 A、B 和 C 都可分配给相同的底层类型,所以您可以使用带有该底层类型参数的函数:func handleFoo(v struct{ Foo map[string]string })

在操场上运行它

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


查看完整回答
反对 回复 2023-05-15
?
拉丁的传说

TA贡献1789条经验 获得超8个赞

你可以尝试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

    }

}


查看完整回答
反对 回复 2023-05-15
  • 3 回答
  • 0 关注
  • 108 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信