首页 >后端开发 >Golang >如何使用泛型在 Go 中使用具有公共成员的不同结构?

如何使用泛型在 Go 中使用具有公共成员的不同结构?

Susan Sarandon
Susan Sarandon原创
2024-10-26 15:29:30790浏览

How to Work with Different Structs with Common Members in Go Using Generics?

使用泛型来处理具有通用成员的不同结构

在 Go 中,您可能会遇到这样的场景:您想要创建运行于共享共同成员的不同结构。然而,Go 1.18 尚不支持跨联合类型约束直接访问此类公共字段。

挑战:

考虑两个消息结构,Message 和 MulticastMessage,每个包含相同类型的字段,例如Android。您想要定义一个通用函数来将这些字段添加到两个结构中。但是,使用仅限于包含两个结构体的接口的类型参数不允许直接访问它们的公共字段。

解决方案:

解决方案 1:类型开关

如果只涉及几个结构体,可以使用类型开关:

<code class="go">func highPriority[T firebaseMessage](message T) T {
    switch m := any(message).(type) {
    case *messaging.Message:
        setConfig(m.Android)
    case *messaging.MulticastMessage:
        setConfig(m.Android)
    }
    return message
}</code>

解决方案2:使用方法包装

对于大量结构体,请考虑使用实现通用功能的方法包装每个结构体:

<code class="go">type wrappedMessage interface {
    *MessageWrapper | *MultiCastMessageWrapper
    SetConfig(c foo.Config)
}

func highPriority[T wrappedMessage](message T) T {
    message.SetConfig(messaging.Android{"some-value"})
    return message
}</code>

解决方案 3:反射

如果您有很多结构体,反射可能是一个更好的选择,尽管它需要可寻址的结构体和字段:

<code class="go">func highPriority[T firebaseMessage](message T) T {
    cfg := &messaging.Android{}
    reflect.ValueOf(message).Elem().FieldByName("Android").Set(reflect.ValueOf(cfg))
    return message
}</code>

注释和替代方案:

  • 如果常见成员是方法,您可能需要为每个约束类型显式实现这些方法。
  • 另一种方法是对公共成员使用自定义接口。然而,这需要修改原始结构,这可能并非在所有情况下都可行。

以上是如何使用泛型在 Go 中使用具有公共成员的不同结构?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn