这是我的问题的一个人为的例子,所以请忽略这个问题是通过使用带有json可选参数的单一结构来解决的。

给定:

    {
        "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
                }
            case "work":
                dst := &AddressWork{}
                err := json.Unmarshal(*value, dst)
                if err != nil {
                    return err
                } else {
                    self.AddressMap[key] = dst
                }
            default:
                continue
        }
    }
}
nameaddress_dict

我尝试了以下方法,并很快意识到为什么它不起作用。

    err = json.Unmarshal(b, self)
    if err != nil {
        return err
    }