dsc7188 2015-06-16 17:29
浏览 28
已采纳

在Go中将JSON解组到地图中

I'm having trouble figuring out how to load a "subsection" of JSON file into a map element. 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:

{
    "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("
JSON: %+v
", 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("
JSON: %+v
", s)
}

The Vals map isn't loaded. 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("
JSON: %+v
", s)
}
  • 写回答

1条回答 默认 最新

  • douqin0676 2015-06-16 17:32
    关注

    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. You created a struct to wrap it but a blob of json like this;

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

    Actually can unmarshal directly into 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. 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".

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度