首頁  >  文章  >  後端開發  >  如何使用泛型在 Go 中使用具有公共成員的不同結構?

如何使用泛型在 Go 中使用具有公共成員的不同結構?

Susan Sarandon
Susan Sarandon原創
2024-10-26 15:29:30693瀏覽

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