什么';在Go中维护未解析的JSON字段的最佳方法是什么?
我想将JSON blob解码成Go结构,对其进行操作,并将其编码回JSON。但是,JSON中有一些与我的结构无关的动态字段,我希望在序列化回JSON时维护它们 例如:什么';在Go中维护未解析的JSON字段的最佳方法是什么?,json,encoding,go,decoding,lossless,Json,Encoding,Go,Decoding,Lossless,我想将JSON blob解码成Go结构,对其进行操作,并将其编码回JSON。但是,JSON中有一些与我的结构无关的动态字段,我希望在序列化回JSON时维护它们 例如: { "name": "Joe Smith", "age": 42, "phone": "614-555-1212", "debug": True, "codeword": "wolf" } type Person struct { Name string Age uint Phon
{ "name": "Joe Smith",
"age": 42,
"phone": "614-555-1212",
"debug": True,
"codeword": "wolf" }
type Person struct {
Name string
Age uint
Phone string
}
var p Person
json.Unmarshal(data, &p)
// Happy birthday
p.Age++
data, _ = json.Marshal(p)
// Any way to maintain the "debug" and "codeword" fields -- which might not
// be known ahead of time?
我知道有一种可能是把所有的东西都解码成一个map[string]接口{}
,但是,当你这么做的时候,事情会变得很糟糕吗
有什么方法可以做到两全其美吗?使用
编码/json
无法解码结构并将未知字段保存在同一级别以供以后重新编码。您可以选择不使用类型解码结构的一部分,如下所示:
type Person struct {
Name string
Address json.RawMessage
}
您可以通过实现自己的方法来解决这一问题,该方法将文档解码为映射,并将未知键保存在结构的字段中,然后有一个对应项在封送处理之前将字段放回原处
出于好奇,您正在寻找的功能确实存在于中,通过,其目标是精确地解决您正在描述的用例。包对于此类工作非常方便。事实证明,我编写了自己的库来实现这一点: 它构建在之上,将解析后的JSON状态保持在
simplejson.JSON
中,并在结构被封送或取消封送时在它和结构之间代理
用法示例:
package main
import (
"encoding/json"
"fmt"
"time"
"github.com/joeshaw/json-lossless"
)
type Person struct {
lossless.JSON `json:"-"`
Name string `json:"name"`
Age int `json:"age"`
Birthdate time.Time `json:"birthdate"`
}
func (p *Person) UnmarshalJSON(data []byte) error {
return p.JSON.UnmarshalJSON(p, data)
}
func (p Person) MarshalJSON() []byte, error) {
return p.JSON.MarshalJSON(p)
}
var jsondata = []byte(`
{"name": "David Von Wolf",
"age": 33,
"birthdate": "1980-09-16T10:44:40.295451647-04:00",
"phone": "614-555-1212"}
`)
func main() {
var p Person
err := json.Unmarshal(jsondata, &p)
if err != nil {
panic(err)
}
// Set values on the struct
p.Age++
// Set arbitrary keys not in the struct
p.Set("title", "Chief Wolf")
fmt.Printf("%#v\n", p)
data, err := json.Marshal(p)
if err != nil {
panic(err)
}
fmt.Println(string(data))
}
打印件(由我为可读性而格式化):
的确我似乎正在解决的解决方案是首先使用go simplejson进行反序列化,然后编写我自己的基于反射的代码在
simplejson.Json
对象和所需结构之间封送。
main.Person{JSON:lossless.JSON{json:(*simplejson.Json)(0x21020a190)},
Name:"David Von Wolf",
Age:34,
Birthdate:time.Time{sec:62473560280,
nsec:295451647,
loc:(*time.Location)(0x16de60)}}
{"age":34,
"birthdate":"1980-09-16T10:44:40.295451647-04:00",
"name":"David Von Wolf",
"phone":"614-555-1212",
"title": "Chief Wolf"}