首页  >  文章  >  后端开发  >  如何编写通用函数来处理 Go 中外部包中具有公共成员的结构?

如何编写通用函数来处理 Go 中外部包中具有公共成员的结构?

Linda Hamilton
Linda Hamilton原创
2024-10-27 09:49:30949浏览

How to Write a Generic Function for Handling Structs with Common Members from an External Package in Go?

用于处理具有外部包中的公共成员的不同结构体的通用函数

简介

编写通用函数来操作共享公共成员的多个结构体可能具有挑战性,特别是当这些结构属于外部包时。本文探讨了解决此场景的各种解决方案。

问题定义

考虑编写一个向 Firebase 消息结构(包括 Message 和 MulticastMessage)添加特定字段的函数。这两个结构体都包含相同类型的 Android 和 APNS 字段,但它们没有显式声明彼此之间的关系。

尝试和错误

最初,人们可能会尝试定义一个通用接口 firebaseMessage ,并按如下方式实现该函数:

<code class="go">type firebaseMessage interface {
    *messaging.Message | *messaging.MulticastMessage
}

func highPriority[T firebaseMessage](message T) T {
    message.Android = &amp;messaging.AndroidConfig{...}
    ....
    return message
}</code>

但是,由于错误“message.Android undefined (type T has no field or method 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)
}

type MessageWrapper struct {
    messaging.Message
}

func (w *MessageWrapper) SetConfig(cfg messaging.Android) {
    *w.Android = cfg
}

// same for MulticastMessageWrapper</code>

解决方案 3:反射

对于结构体较多的情况,反射可能是更合适的解决方案。

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

请注意,由于此方法使用反射,因此必须确保字段可寻址。

结论

根据具体要求,适当的解决方案可能会有很大差异。本文提供了几种在 Go 中处理此类场景的可行选项。

以上是如何编写通用函数来处理 Go 中外部包中具有公共成员的结构?的详细内容。更多信息请关注PHP中文网其他相关文章!

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