将json数组解组为struct

时间:2014-03-20 09:39:19

标签: json go

我有一系列自定义值

[
    1,
    "test",
    { "a" : "b" }
]

我可以在[]界面{}中解组,但这不是我想要的。

我想将这个数组解组为struct

type MyType struct {
    Count int
    Name string
    Relation map[string]string
}

Go中是否可以使用标准库或侧库?

4 个答案:

答案 0 :(得分:2)

您可以使用github.com/ugorji/go/codec,它可以将数组解组为结构:

  

将结构编码为数组,并从数据流中的数组解码结构

虽然图书馆宣传“编码/ 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)
}

答案 1 :(得分:1)

其他答案似乎太复杂了,这是另一种方法:

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)
}

https://eagain.net/articles/go-json-array-to-struct

答案 2 :(得分:0)

这是一个元组,将元组解组成一个结构是完全没问题的,除了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)
}

以下是完整示例:http://play.golang.org/p/QVA-1ynn15

答案 3 :(得分:-1)

因为你的json在数组中保存了不同类型的值,所以不可能简单地解析它。如果您可以控制json输入的格式,请将{}中的三个值包装成一个对象,如下所示:

[
    {
        "Count": 1,
        "Name": "test",
        "Relation": { "a" : "b" }
     }
]

然后解析到你的结构应该可行。

如果您无法控制json输入。将其解析为[] interface {},然后手动将值分配给结构。即使这可能会变得棘手,取决于您希望支持的可能响应的复杂性。

请注意,这个问题指出了golangs json解析方法的核心限制,因此 - 据我所知 - 它也无法通过库解决。