首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用一些已知的和一些未知的字段名称解组JSON

使用一些已知的和一些未知的字段名称解组JSON
EN

Stack Overflow用户
提问于 2015-10-30 21:06:06
回答 7查看 62K关注 0票数 81

我有以下JSON

代码语言:javascript
复制
{"a":1, "b":2, "?":1, "??":1}

我知道它有"a“和"b”字段,但我不知道其他字段的名称。所以我想用下面的类型对它进行解组:

代码语言:javascript
复制
type Foo struct {
  // Known fields
  A int `json:"a"`
  B int `json:"b"`
  // Unknown fields
  X map[string]interface{} `json:???` // Rest of the fields should go here.
}

我该怎么做?

EN

回答 7

Stack Overflow用户

发布于 2015-10-30 22:02:45

两次解组

一种选择是解组两次:一次解组为Foo类型的值,另一次解组为map[string]interface{}类型的值,并删除键"a""b"

代码语言:javascript
复制
type Foo struct {
    A int                    `json:"a"`
    B int                    `json:"b"`
    X map[string]interface{} `json:"-"` // Rest of the fields should go here.
}

func main() {
    s := `{"a":1, "b":2, "x":1, "y":1}`
    f := Foo{}
    if err := json.Unmarshal([]byte(s), &f); err != nil {
        panic(err)
    }

    if err := json.Unmarshal([]byte(s), &f.X); err != nil {
        panic(err)
    }
    delete(f.X, "a")
    delete(f.X, "b")

    fmt.Printf("%+v", f)
}

输出(在Go Playground上试用):

代码语言:javascript
复制
{A:1 B:2 X:map[x:1 y:1]}

解组一次和手动处理

另一种选择是将数据解组到map[string]interface{}中,然后手动处理Foo.AFoo.B字段:

代码语言:javascript
复制
type Foo struct {
    A int                    `json:"a"`
    B int                    `json:"b"`
    X map[string]interface{} `json:"-"` // Rest of the fields should go here.
}

func main() {
    s := `{"a":1, "b":2, "x":1, "y":1}`
    f := Foo{}
    if err := json.Unmarshal([]byte(s), &f.X); err != nil {
        panic(err)
    }
    if n, ok := f.X["a"].(float64); ok {
        f.A = int(n)
    }
    if n, ok := f.X["b"].(float64); ok {
        f.B = int(n)
    }
    delete(f.X, "a")
    delete(f.X, "b")

    fmt.Printf("%+v", f)
}

输出相同(Go Playground):

代码语言:javascript
复制
{A:1 B:2 X:map[x:1 y:1]}
票数 50
EN

Stack Overflow用户

发布于 2015-10-30 22:02:16

它不是很好,但是您可以通过实现Unmarshaler来实现它

代码语言:javascript
复制
type _Foo Foo

func (f *Foo) UnmarshalJSON(bs []byte) (err error) {
    foo := _Foo{}

    if err = json.Unmarshal(bs, &foo); err == nil {
        *f = Foo(foo)
    }

    m := make(map[string]interface{})

    if err = json.Unmarshal(bs, &m); err == nil {
        delete(m, "a")
        delete(m, "b")
        f.X = m
    }

    return err
}

为了在解码时避免递归,必须使用_Foo类型。

票数 24
EN

Stack Overflow用户

发布于 2017-06-01 21:23:57

最简单的方法是使用这样的接口:

代码语言:javascript
复制
var f interface{}
s := `{"a":1, "b":2, "x":1, "y":1}`

if err := json.Unmarshal([]byte(s), &f); err != nil {
    panic(err)
}

Go Playground example

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33436730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档