2 回答

TA貢獻1810條經驗 獲得超4個贊
我不知道這是否是一個好的解決方案,我還是新手,但無論如何,你可以使用json。RawMessage并將財產的解封“延遲”到兩個單獨的結構字段之一。例如:wlan
package main
import (
"encoding/json"
"fmt"
)
// Data contains data about the Fritz!Box. (other fields omitted for brevity)
type Data struct {
Language string `json:"language"`
NewsURL string `json:"NEWSLETTER_URL"`
WLanRaw *json.RawMessage `json:"wlan"`
WLanBool bool `json:"-"`
WLanInfo *WLanInfo `json:"-"`
}
// WLanInfo contains infos about the Wireless Lan
type WLanInfo struct {
Txt string `json:"txt"`
Led string `json:"led"`
Title string `json:"title"`
Link string `json:"link"`
Tooltip string `json:"tooltip"`
}
func UnmarshalData(raw []byte, data *Data) error {
if err := json.Unmarshal(raw, data); err != nil {
return err
}
switch string(*data.WLanRaw) {
case "true", "false":
json.Unmarshal(*data.WLanRaw, &data.WLanBool)
default:
if err := json.Unmarshal(*data.WLanRaw, &data.WLanInfo); err != nil {
return err
}
}
return nil
}
func main() {
jsonBool := []byte(`
{
"language": "it",
"NEWSLETTER_URL": "https://example.com/news",
"wlan": true
}`)
jsonInfo := []byte(`
{
"language": "it",
"NEWSLETTER_URL": "https://example.com/news",
"wlan": {
"txt": "footxt",
"led": "fooled",
"title": "hello",
"link": "bar",
"tooltip": "baz"
}
}`)
// error handling omitted
var dataBool Data
UnmarshalData(jsonBool, &dataBool)
fmt.Printf("%+v\n\n", dataBool)
var dataInfo Data
UnmarshalData(jsonInfo, &dataInfo)
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}
$

TA貢獻1830條經驗 獲得超3個贊
你可以實現 json。Unmarshaler 和 json.封送線接口。
type WLan struct {
Bool *bool `json:"-"`
Txt string `json:"txt"`
Led string `json:"led"`
Title string `json:"title"`
Link string `json:"link"`
Tooltip string `json:"tooltip"`
}
// implements json.Unmarshaler
func (w *WLan) UnmarshalJSON(data []byte) error {
if len(data) > 0 && (data[0] == 't' || data[0] == 'f') { // seems to be a bool
w.Bool = new(bool)
return json.Unmarshal(data, w.Bool)
}
if len(data) > 1 && data[0] == '{' && data[len(data)-1] == '}' { // it's an object
// type W and the conversion (*W)(w) are required to
// prevent encoding/json from invoking the UnmarshalJSON
// method recursively causing a stack overflow
type W WLan
return json.Unmarshal(data, (*W)(w))
}
return nil // or error, up to you
}
// implements json.Marshaler
func (w WLan) MarshalJSON() ([]byte, error) {
if w.Bool != nil {
return json.Marshal(*w.Bool)
}
// Same as with UnmarshalJSON, type W and the conversion W(w) are
// required to prevent encoding/json from invoking the MarshalJSON
// method recursively causing a stack overflow
type W WLan
return json.Marshal(W(w))
}
https://play.golang.org/p/s72zt4ny7Pv
- 2 回答
- 0 關注
- 112 瀏覽
添加回答
舉報