在下联运期间处理不同类型的参数

我正在使用弗里茨的一些API!Box router,我想在一个体面的结构中取消json响应,只需要找到一个好方法来做到这一点。


有时在API响应中,WLan参数是boool,有时是这种类型的对象。


// WLan contains info about the Wireless Lan

type WLan struct {

    Txt     string `json:"txt"`

    Led     string `json:"led"`

    Title   string `json:"title"`

    Link    string `json:"link"`

    Tooltip string `json:"tooltip"`

}

如果需要有关代码的详细信息,可以使用 github 存储库。


我需要添加布尔wlan参数,我试图复制“Data”结构并更改名称,但该解决方案对我来说听起来很糟糕。


Wlan 包含在以下结构中:


// Data contains data about the Fritz!Box

type Data struct {

    NasLink          string    `json:"naslink"`

    FritzOS          FritzOS   `json:"fritzos"`

    Webdav           int       `json:"webdav,string"`

    Manual           string    `json:"MANUAL_URL"`

    Language         string    `json:"language"`

    AVM              string    `json:"AVM_URL"`

    USBConnect       string    `json:"usbconnect"`

    Foncalls         Foncalls  `json:"foncalls"`

    VPN              VPN       `json:"vpn"`

    Internet         Internet  `json:"internet"`

    DSL              DSL       `json:"dsl"`

    ServicePortalURL string    `json:"SERVICEPORTAL_URL"`

    Comfort          Comfort   `json:"comfort"`

    Changelog        Changelog `json:"changelog"`

    TamCalls         TamCalls  `json:"tamcalls"`

    Lan              External  `json:"lan"`

    USB              External  `json:"usb"`

    FonNum           External  `json:"fonnum"`

    NewsURL          string    `json:"NEWSLETTER_URL"`

    Net              Net       `json:"net"`

    Dect             External  `json:"dect"`

    WLan             WLan      `json:"wlan"`

  //Wlan             bool      `json:"wlan"` # This is the other "case"

}


RISEBY
浏览 90回答 2
2回答

慕莱坞森

我不知道这是否是一个好的解决方案,我还是新手,但无论如何,你可以使用json。RawMessage并将财产的解封“延迟”到两个单独的结构字段之一。例如:wlanpackage mainimport (&nbsp; &nbsp; "encoding/json"&nbsp; &nbsp; "fmt")// Data contains data about the Fritz!Box. (other fields omitted for brevity)type Data struct {&nbsp; &nbsp; Language string&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;`json:"language"`&nbsp; &nbsp; NewsURL&nbsp; string&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;`json:"NEWSLETTER_URL"`&nbsp; &nbsp; WLanRaw&nbsp; *json.RawMessage `json:"wlan"`&nbsp; &nbsp; WLanBool bool&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;`json:"-"`&nbsp; &nbsp; WLanInfo *WLanInfo&nbsp; &nbsp; &nbsp; &nbsp; `json:"-"`}// WLanInfo contains infos about the Wireless Lantype WLanInfo struct {&nbsp; &nbsp; Txt&nbsp; &nbsp; &nbsp;string `json:"txt"`&nbsp; &nbsp; Led&nbsp; &nbsp; &nbsp;string `json:"led"`&nbsp; &nbsp; Title&nbsp; &nbsp;string `json:"title"`&nbsp; &nbsp; Link&nbsp; &nbsp; string `json:"link"`&nbsp; &nbsp; Tooltip string `json:"tooltip"`}func UnmarshalData(raw []byte, data *Data) error {&nbsp; &nbsp; if err := json.Unmarshal(raw, data); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; return err&nbsp; &nbsp; }&nbsp; &nbsp; switch string(*data.WLanRaw) {&nbsp; &nbsp; case "true", "false":&nbsp; &nbsp; &nbsp; &nbsp; json.Unmarshal(*data.WLanRaw, &data.WLanBool)&nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; if err := json.Unmarshal(*data.WLanRaw, &data.WLanInfo); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return err&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return nil}func main() {&nbsp; &nbsp; jsonBool := []byte(`{&nbsp; &nbsp; "language": "it",&nbsp; &nbsp; "NEWSLETTER_URL": "https://example.com/news",&nbsp; &nbsp; "wlan": true}`)&nbsp; &nbsp; jsonInfo := []byte(`{&nbsp; &nbsp; "language": "it",&nbsp; &nbsp; "NEWSLETTER_URL": "https://example.com/news",&nbsp; &nbsp; "wlan": {&nbsp; &nbsp; &nbsp; &nbsp; "txt": "footxt",&nbsp; &nbsp; &nbsp; &nbsp; "led": "fooled",&nbsp; &nbsp; &nbsp; &nbsp; "title": "hello",&nbsp; &nbsp; &nbsp; &nbsp; "link": "bar",&nbsp; &nbsp; &nbsp; &nbsp; "tooltip": "baz"&nbsp; &nbsp; }}`)&nbsp; &nbsp; // error handling omitted&nbsp; &nbsp; var dataBool Data&nbsp; &nbsp; UnmarshalData(jsonBool, &dataBool)&nbsp; &nbsp; fmt.Printf("%+v\n\n", dataBool)&nbsp; &nbsp; var dataInfo Data&nbsp; &nbsp; UnmarshalData(jsonInfo, &dataInfo)&nbsp; &nbsp; fmt.Printf("%+v %+v\n", dataInfo, dataInfo.WLanInfo)}$ go build fritz.go$ ./fritz{Language:it NewsURL:https://example.com/news WLanRaw:0xc0000a4060 WLanBool:true WLanInfo:<nil>}{Language:it NewsURL:https://example.com/news WLanRaw:0xc0000a4080 WLanBool:false WLanInfo:0xc0000b0000} &{Txt:footxt Led:fooled Title:hello Link:bar Tooltip:baz}$

牛魔王的故事

你可以实现 json。Unmarshaler 和 json.封送线接口。type WLan struct {&nbsp; &nbsp; Bool&nbsp; &nbsp; *bool&nbsp; `json:"-"`&nbsp; &nbsp; Txt&nbsp; &nbsp; &nbsp;string `json:"txt"`&nbsp; &nbsp; Led&nbsp; &nbsp; &nbsp;string `json:"led"`&nbsp; &nbsp; Title&nbsp; &nbsp;string `json:"title"`&nbsp; &nbsp; Link&nbsp; &nbsp; string `json:"link"`&nbsp; &nbsp; Tooltip string `json:"tooltip"`}// implements json.Unmarshalerfunc (w *WLan) UnmarshalJSON(data []byte) error {&nbsp; &nbsp; if len(data) > 0 && (data[0] == 't' || data[0] == 'f') { // seems to be a bool&nbsp; &nbsp; &nbsp; &nbsp; w.Bool = new(bool)&nbsp; &nbsp; &nbsp; &nbsp; return json.Unmarshal(data, w.Bool)&nbsp; &nbsp; }&nbsp; &nbsp; if len(data) > 1 && data[0] == '{' && data[len(data)-1] == '}' { // it's an object&nbsp; &nbsp; &nbsp; &nbsp; // type W and the conversion (*W)(w) are required to&nbsp; &nbsp; &nbsp; &nbsp; // prevent encoding/json from invoking the UnmarshalJSON&nbsp; &nbsp; &nbsp; &nbsp; // method recursively causing a stack overflow&nbsp; &nbsp; &nbsp; &nbsp; type W WLan&nbsp; &nbsp; &nbsp; &nbsp; return json.Unmarshal(data, (*W)(w))&nbsp; &nbsp; }&nbsp; &nbsp; return nil // or error, up to you}// implements json.Marshalerfunc (w WLan) MarshalJSON() ([]byte, error) {&nbsp; &nbsp; if w.Bool != nil {&nbsp; &nbsp; &nbsp; &nbsp; return json.Marshal(*w.Bool)&nbsp; &nbsp; }&nbsp; &nbsp; // Same as with UnmarshalJSON, type W and the conversion W(w) are&nbsp;&nbsp; &nbsp; // required to prevent encoding/json from invoking the MarshalJSON&nbsp; &nbsp; // method recursively causing a stack overflow&nbsp; &nbsp; type W WLan&nbsp; &nbsp; return json.Marshal(W(w))}https://play.golang.org/p/s72zt4ny7Pv
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go