json - 在 Go 中将 JSON 解码为 map

标签 json dictionary go

我无法弄清楚如何将 JSON 文件的“子部分”加载到 map 元素中。背景:我正在尝试解码一个具有严格结构的有点复杂的配置文件,因此我认为最好解码为“静态”结构而不是接口(interface){}。

例如,这是一个简单的 JSON 文件:

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

此代码有效:

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

但这不是:

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

Vals map 未加载。我究竟做错了什么?感谢您的帮助!

这是一个更好的例子:

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

代码:

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

最佳答案

我相信这是因为您的模型中有额外的间接层。

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

应该够了。如果您指定 map[string]string json 中的对象被识别为该 map 。您创建了一个结构来包装它,但是像这样的 json block ;

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

其实可以直接解码成map[string]string

编辑:基于评论的其他一些模型

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

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

这使您的 3-d 点成为一个静态类型的结构,这很好。如果您想快速而肮脏地进行操作,也可以使用 map[string]map[string]string 这将给出 map 的 map ,因此您可以访问像 FirstSet["a"]["x"] 这样的点值它会返回 "11" .

二次编辑;显然我没有仔细阅读你的代码,因为上面的例子是一样的。基于此,我猜你想要

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

选项。虽然在您编辑后我还不是很清楚。

关于json - 在 Go 中将 JSON 解码为 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30874299/

相关文章:

go - Viper AddConfigPath 仅在当前文件夹中查找文件 "."

javascript - 使用 angularjs 和 ng-repeat 从 JSON 数据创建表

python - 如何对dict元素求和

go - 数字常量的打印类型导致溢出

go - Golang 上的包导入错误

arrays - 将字典数组拆分为字典子数组

PHP:如何防止 json_encode 自动舍入数字?

python - Python 中的任意字典 (JSON) 到更严格的树状字典 (JSON)

json - future 证明 : Is removing a JSON envelope the current best practice?

c++ - 访问 map 的一个 "item"