1 回答

TA貢獻1898條經(jīng)驗 獲得超8個贊
在 Go 1.18 中,您不能訪問公共字段1,也不能訪問類型參數(shù)的公共方法2。這些特性之所以不能工作,僅僅是因為它們還沒有在該語言中可用。如鏈接線程所示,常見的解決方案是為接口約束指定方法。
但是,類型*messaging.Message和*messaging.MulticastMessage沒有通用的訪問器方法,并且在您無法控制的庫包中聲明。
解決方案1:類型開關(guān)
如果聯(lián)合中的類型較少,則此方法可以正常工作。
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
}
func setConfig(cfg *messaging.AndroidConfig) {
// just assuming the config is always non-nil
*cfg = &messaging.AndroidConfig{}
}
游樂場:https ://go.dev/play/p/9iG0eSep6Qo
解決方案 2:包裝方法
這歸結(jié)為如何在 Go 中向現(xiàn)有類型添加新方法?然后將該方法添加到約束中。如果你有很多結(jié)構(gòu),它仍然不太理想,但代碼生成可能會有所幫助:
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
func highPriority[T wrappedMessage](message T) T {
// now you can call this common method
message.SetConfig(messaging.Android{"some-value"})
return message
}
游樂場:https ://go.dev/play/p/JUHp9Fu27Yt
方案三:反射
如果你有很多結(jié)構(gòu),你可能最好使用反射。在這種情況下,類型參數(shù)不是嚴格需要的,但有助于提供額外的類型安全。請注意,結(jié)構(gòu)和字段必須是可尋址的才能起作用。
func highPriority[T firebaseMessage](message T) T {
cfg := &messaging.Android{}
reflect.ValueOf(message).Elem().FieldByName("Android").Set(reflect.ValueOf(cfg))
return message
}
游樂場:https ://go.dev/play/p/3DbIADhiWdO
- 1 回答
- 0 關(guān)注
- 116 瀏覽
添加回答
舉報