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

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

結(jié)構(gòu)中的golang解組(反序列化)變量類型字典

結(jié)構(gòu)中的golang解組(反序列化)變量類型字典

Go
白衣非少年 2022-06-21 10:00:49
這是我的問題的人為示例,因此請忽略這是通過使用帶有 json 可選參數(shù)的奇異結(jié)構(gòu)來解決的。鑒于:    {        "name": "alice",        "address_dict": {                            "home": { "address": "123 st" },                            "work": { "address": "456 rd", "suite": "123"}                        }    }type AddressIf interface{}type AddressHome {    Address string `json:"address"`}type AddressWork {    Address string `json:"address"`    Suite string `json:"suite"`}type Contact struct {    Name string `json:"name"`    AddressMap map[string]AddressIf `json:"address_map"`}func(self *Contact) UnmarshalJSON(b []byte) error {    var objMap map[string]*json.RawMessage    err := json.Unmarshal(b, &objMap    if err != nil {        return err    }    var rawAddressMap map[string]*json.RawMessage    err = json.Unmarshal(*objMap["address_map"], &rawAddressMap)    if err != nil {        return err    }    // how do we unmarshal everything else in the struct, and only override the handling of address map???    // <failing code block is here - beg - just a tad, just a tad, just a tad - recursive>    err = json.Unmarshal(b, self)    if err != nil {        return err    }    // <failing code block is here - end>    if nil == self.AddressMap {        self.AddressMap = make(map[string]AddressIf)    }    for key, value := range rawAddressMap {        switch key {            case "home":                dst := &AddressHome{}                err := json.Unmarshal(*value, dst)                if err != nil {                    return err                } else {                    self.AddressMap[key] = dst                }        }    }}我只有name這個 json 示例位中的參數(shù),但假設(shè)我的代碼中有更多參數(shù)。address_dict有沒有辦法對所有參數(shù)使用普通/默認解組,然后只手動接管?我嘗試了以下方法,并很快意識到為什么它不起作用。    err = json.Unmarshal(b, self)    if err != nil {        return err    }
查看完整描述

2 回答

?
偶然的你

TA貢獻1841條經(jīng)驗 獲得超3個贊

另一個答案的替代方法是聲明一個命名map[string]AddressIf類型并讓它實現(xiàn)json.Unmarshaler接口,然后你不必做任何臨時/匿名類型和轉(zhuǎn)換舞蹈。


type AddressMap map[string]AddressIf


func (m *AddressMap) UnmarshalJSON(b []byte) error {

    if *m == nil {

        *m = make(AddressMap)

    }


    raw := make(map[string]json.RawMessage)

    if err := json.Unmarshal(b, &raw); err != nil {

        return err

    }


    for key, val := range raw {

        switch key {

        case "home":

            dst := new(AddressHome)

            if err := json.Unmarshal(val, dst); err != nil {

                return err

            }

            (*m)[key] = dst

        case "work":

            dst := new(AddressWork)

            if err := json.Unmarshal(val, dst); err != nil {

                return err

            }

            (*m)[key] = dst

        }

    }

    return nil

}

https://play.golang.org/p/o7zV8zu9g5X


查看完整回答
反對 回復(fù) 2022-06-21
?
收到一只叮咚

TA貢獻1821條經(jīng)驗 獲得超5個贊

為避免復(fù)制聯(lián)系人字段,請使用對象嵌入來隱藏需要特殊處理的字段。


使用工廠模式來消除跨地址類型的代碼重復(fù)。


有關(guān)更多信息,請參閱評論:


var addressFactories = map[string]func() AddressIf{

    "home": func() AddressIf { return &AddressHome{} },

    "work": func() AddressIf { return &AddressWork{} },

}


func (self *Contact) UnmarshalJSON(b []byte) error {


    // Declare type with same base type as Contact. This

    // avoids recursion below because this type does not

    // have Contact's UnmarshalJSON method.

    type contactNoMethods Contact


    // Unmarshal to this value. The Contact.AddressMap

    // field is shadowed so we can handle unmarshal of

    // each value in the map.

    var data = struct {

        *contactNoMethods

        AddressMap map[string]json.RawMessage `json:"address_map"`

    }{

        // Note that all fields except AddressMap are unmarshaled

        // directly to Contact.

        (*contactNoMethods)(self),

        nil,

    }


    if err := json.Unmarshal(b, &data); err != nil {

        return err

    }


    // Unmarshal each addresss...


    self.AddressMap = make(map[string]AddressIf, len(data.AddressMap))

    for k, raw := range data.AddressMap {

        factory := addressFactories[k]

        if factory == nil {

            return fmt.Errorf("unknown key %s", k)

        }

        address := factory()

        if err := json.Unmarshal(raw, address); err != nil {

            return err

        }

        self.AddressMap[k] = address

    }

    return nil

}

 

在對該問題的評論中,OP 表示不應(yīng)使用其他類型。這個答案使用了兩種額外contactNoMethods的類型(和匿名類型data)。


查看完整回答
反對 回復(fù) 2022-06-21
  • 2 回答
  • 0 關(guān)注
  • 136 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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