第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用外部包中的公共成員處理不同結(jié)構(gòu)的通用函數(shù)?

使用外部包中的公共成員處理不同結(jié)構(gòu)的通用函數(shù)?

Go
繁星淼淼 2022-12-26 10:16:22
我想編寫一個可以將某些字段添加到 Firebase 消息結(jié)構(gòu)的函數(shù)。有兩種不同類型的消息,Message和MulticastMessage,它們都包含相同類型的Android和APNS字段,但是消息類型之間沒有明確聲明的關(guān)系。我想我應(yīng)該能夠做到這一點:type firebaseMessage interface {    *messaging.Message | *messaging.MulticastMessage}func highPriority[T firebaseMessage](message T) T {    message.Android = &messaging.AndroidConfig{...}    ....    return message}但它給出了錯誤message.Android undefined (type T has no field or method Android)。我也不會寫switch m := message.(type)( cannot use type switch on type parameter value message (variable of type T constrained by firebaseMessage))。我可以寫switch m := any(message).(type),但我仍然不確定這是否會達到我想要的效果。我從對聯(lián)合和類型約束感到困惑的人那里發(fā)現(xiàn)了其他一些 SO 問題,但我看不到任何有助于解釋為什么這不起作用的答案(可能是因為我試圖將它與結(jié)構(gòu)而不是接口一起使用?)或者什么聯(lián)合類型約束實際上有用。
查看完整描述

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


查看完整回答
反對 回復(fù) 2022-12-26
  • 1 回答
  • 0 關(guān)注
  • 116 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號