简体   繁体   English

在Go中将JSON解组到地图中

[英]Unmarshal JSON into a map in Go

I'm having trouble figuring out how to load a "subsection" of JSON file into a map element. 我在弄清楚如何将JSON文件的“小节”加载到地图元素中时遇到了麻烦。 Background: I'm trying to unmarshal a somewhat complicated configuration file which has a strict structure, so I assume it's preferable to unmarshal into a "static" structure rather than into an interface{}. 背景:我正在尝试解封具有严格结构的有些复杂的配置文件,因此我认为最好将其解封为“静态”结构,而不是解封为接口{}。

Here's a simple JSON file for example: 这是一个简单的JSON文件,例如:

{
    "set1": {
        "a":"11",
        "b":"22",
        "c":"33"
    }
}

This code works: 此代码有效:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "os"
)

type JSONType struct {
    FirstSet ValsType `json:"set1"`
}

type ValsType struct {
    A string `json:"a"`
    B string `json:"b"`
    C string `json:"c"`
}

func main() {
    file, e := ioutil.ReadFile("./test1.json")
    if e != nil {
        fmt.Println("file error")
        os.Exit(1)
    }
    var s JSONType
    json.Unmarshal([]byte(file), &s)
    fmt.Printf("\nJSON: %+v\n", s)
}

But this doesn't: 但这不是:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "os"
)

type JSONType struct {
    FirstSet ValsType `json:"set1"`
}

type ValsType struct {
    Vals map[string]string
}

func main() {
    file, e := ioutil.ReadFile("./test1.json")
    if e != nil {
        fmt.Println("file error")
        os.Exit(1)
    }

    var s JSONType
    s.FirstSet.Vals = map[string]string{}
    json.Unmarshal([]byte(file), &s)
    fmt.Printf("\nJSON: %+v\n", s)
}

The Vals map isn't loaded. 未加载Vals地图。 What am I doing wrong? 我究竟做错了什么? Thanks for any help! 谢谢你的帮助!

Here's a better example: 这是一个更好的例子:

{
    "set1": {
        "a": {
            "x": "11",
            "y": "22",
            "z": "33"
        },
        "b": {
            "x": "211",
            "y": "222",
            "z": "233"
        },
        "c": {
            "x": "311",
            "y": "322",
            "z": "333"
        },
    }
}

Code: 码:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "os"
)

type JSONType struct {
    FirstSet map[string]ValsType `json:"set1"`
}

type ValsType struct {
    X string `json:"x"`
    Y string `json:"y"`
    Z string `json:"z"`
}

func main() {
    file, e := ioutil.ReadFile("./test1.json")
    if e != nil {
        fmt.Println("file error")
        os.Exit(1)
    }
    var s JSONType
    json.Unmarshal([]byte(file), &s)
    fmt.Printf("\nJSON: %+v\n", s)
}

I believe that is because you have extra layer of indirection in your models. 我相信这是因为您的模型中具有额外的间接层。

type JSONType struct {
    FirstSet map[string]string `json:"set1"`
}

Should suffice. 应该足够了。 if you specify map[string]string the object in json is recognized as that map. 如果指定map[string]string ,则json中的对象将被识别为该地图。 You created a struct to wrap it but a blob of json like this; 您创建了一个结构来包装它,但是像这样的json块;

{
    "a":"11",
    "b":"22",
    "c":"33"
}

Actually can unmarshal directly into map[string]string 实际上可以直接将其解编为map[string]string

EDIT: Some other models based on the comment 编辑:基于注释的其他一些模型

type JSONType struct {
    FirstSet map[string]Point `json:"set1"`
}

type Point struct {
     X string `json:"x"`
     Y string `json:"y"`
     Z string `json:"z"`
}

This makes your 3-d point a statically typed struct which is fine. 这会使您的3维点成为静态类型的结构,这很好。 If you wanted to do the quick and dirty you could also just use map[string]map[string]string which would give a map of maps so you could access the point values like FirstSet["a"]["x"] and it would return "11" . 如果您想快速又脏乱地使用,也可以使用map[string]map[string]string来提供地图图,这样您就可以访问诸如FirstSet["a"]["x"]和它将返回"11"

Second edit; 第二次编辑; clearly I didn't read you code that closely since the above example is the same. 显然,由于上面的示例是相同的,所以我没有仔细阅读过您的代码。 Based on that I would guess you want the 基于此,我想您想要

 FirstSet map[string]map[string]string `json:"set1"`

option. 选项。 Though it's not entirely clear to me after your edit. 尽管您修改后对我来说还不是很清楚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM