編寫通用函數來操作共享公共成員的多個結構體可能具有挑戰性,特別是當這些結構屬於外部套件時。本文探討了解決此場景的各種解決方案。
考慮編寫一個在 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 = &messaging.AndroidConfig{...} .... return message }</code>
但是,由於錯誤「message .Android undefined (type T has no field or method Android)”,此方法失敗。
一個簡單的解決方案涉及使用類型開關來單獨處理每個特定的結構類型:
<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 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>
對於結構體較多的情況,反射可能是更合適的解決方案。
<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 中處理此類場景的可行選項。
以上是如何編寫通用函數來處理 Go 中外部套件中具有公共成員的結構?的詳細內容。更多資訊請關注PHP中文網其他相關文章!