使用泛型來處理具有通用成員的不同結構
在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中文網其他相關文章!