我有一个自定义值的数组
[
1,
"test",
{ "a" : "b" }
]
我可以将其反序列化为 []interface{},但这不是我想要的。
我希望将此数组反序列化为结构体。
type MyType struct {
Count int
Name string
Relation map[string]string
}
在Go语言中,使用标准库或者其他库是否可以实现这个功能?
我有一个自定义值的数组
[
1,
"test",
{ "a" : "b" }
]
我可以将其反序列化为 []interface{},但这不是我想要的。
我希望将此数组反序列化为结构体。
type MyType struct {
Count int
Name string
Relation map[string]string
}
package main
import (
"encoding/json"
"fmt"
)
type myType struct {
count int
name string
relation map[string]string
}
func (t *myType) UnmarshalJSON(b []byte) error {
a := []interface{}{&t.count, &t.name, &t.relation}
return json.Unmarshal(b, &a)
}
func main() {
var t myType
json.Unmarshal([]byte(`[1, "test", {"a": "b"}]`), &t)
fmt.Printf("%+v\n", t)
}
将结构体编码为数组,并从数据流中解码结构体
尽管该库宣传是“encoding/json的即插即用替代品”,但这仅适用于json:
标记。因此,您需要使用codec.Decoder
而不是json.Unmarshal
:
package main
import "fmt"
import "github.com/ugorji/go/codec"
type MyType struct {
Count int
Name string
Relation map[string]string
}
func main() {
x := &MyType{}
data := []byte(`[1,"test",{"a":"b"}]`)
codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(x)
fmt.Println(x)
}
encoding/json
不支持这样做。// UnmarshalJSONTuple unmarshals JSON list (tuple) into a struct.
func UnmarshalJSONTuple(text []byte, obj interface{}) (err error) {
var list []json.RawMessage
err = json.Unmarshal(text, &list)
if err != nil {
return
}
objValue := reflect.ValueOf(obj).Elem()
if len(list) > objValue.Type().NumField() {
return fmt.Errorf("tuple has too many fields (%v) for %v",
len(list), objValue.Type().Name())
}
for i, elemText := range list {
err = json.Unmarshal(elemText, objValue.Field(i).Addr().Interface())
if err != nil {
return
}
}
return
}
所以你只需要提供UnmarshalJSON
方法:
func (this *MyType) UnmarshalJSON(text []byte) (err error) {
return UnmarshalJSONTuple(text, this)
}
由于您的 JSON 数组中包含不同类型的值,因此无法简单地使用 Go 解析它。如果您可以控制 JSON 输入的格式,请将三个值包装在 {}
中以形成对象,例如:
[
{
"Count": 1,
"Name": "test",
"Relation": { "a" : "b" }
}
]
然后解析到你的结构体应该可以工作。
如果您无法控制json输入。将其解析为[]interface{},然后手动将值分配给您的结构体。尽管这可能会变得棘手,具体取决于您想支持的可能响应的复杂性。
请注意,此问题指向golang json解析方法的核心限制,因此 - 就我所知 - 它也不能通过库来解决。