使用外部套件時,定義對包含公共成員的結構進行操作的泛型函數可能具有挑戰性。本文探討了一個問題,即嘗試建立通用函數來修改兩個不同 Firebase 訊息結構 Message 和 MulticastMessage 的共用欄位。
儘管有與Android配置欄位類似,這些結構沒有明確關係,嘗試直接使用類型參數存取它們的公共屬性會導致錯誤。原因是 Go 1.18 尚不支援存取類型參數的公共欄位或方法,如連結執行緒所述。
為了解決此問題,有幾個解決方案建議:
如果涉及的類型數量有限,可以使用類型切換語句來存取共用欄位:
<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>
此方法涉及使用要在泛型函數中使用的附加方法建立包裝器結構:
<code class="go">type MessageWrapper struct { messaging.Message } func (w *MessageWrapper) SetConfig(cfg messaging.Android) { *w.Android = cfg }</code>
然後泛型函數可以存取此通用方法:
<code class="go">func highPriority[T wrappedMessage](message T) T { message.SetConfig(messaging.Android{"some-value"}) return message }</code>
如果結構體數量較多,可以使用反射來動態存取共享欄位:
<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中文網其他相關文章!