json - 如何在Go中解析json?

标签 json go

我不知道如何将json解析为golang中的结构,这看起来很简单,但我在从文件中获取数据时遇到了问题。
我知道我必须声明这样的结构

type Title1 struct{
  Opt1 string `json:"opt1"`
  Opt2 string `json:"opt2"`
  Opt3 string `json:"opt3"`
  Opt4 string `json:"opt4"`
}

type Title2 struct{
  Opt1 string `json:"opt1"`
  Opt2 string `json:"opt2"`
  Opt3 string `json:"opt3"`
  Opt4 string `json:"opt4"`
}
// Read from the file
data, error := ioutil.ReadFile("file.json")
  if error != nil{
    log.Panic(error)
  } else {
    data := Title1{}
    _ = json.Unmarshal([]byte(data), Title1)
    log.Println("Opt1: " + Title1.Opt1)
  }
}

{
  "title1": {
    "opt1": "..."
    "opt2": "...",
    "opt3": "...",
    "opt4": "...",
  }
  "title2": {
    "opt1": "..."
    "opt2": "...",
    "opt3": "...",
    "opt4": "...",
  }
}

但我不知道该如何指定使用哪个标题。

最佳答案

有几件事你需要先改变。
JSON格式不正确。缺少一些分号。如果没有有效的json输入,解组最终将失败。正确的格式是,

{
  "title1": {
    "opt1": "...", 
    "opt2": "...",
    "opt3": "...",
    "opt4": "..."
  },
  "title2": {
    "opt1": "...",
    "opt2": "...",
    "opt3": "...",
    "opt4": "..."
  }
}

由于json同时包含title1title2字段,因此需要一个结构,其中两个字段都可用。初始化结构的一种方法可以是,(playground link
type Title1 struct {
    Opt1 string `json:"opt1"`
    Opt2 string `json:"opt2"`
    Opt3 string `json:"opt3"`
    Opt4 string `json:"opt4"`
}

type Title2 struct {
    Opt1 string `json:"opt1"`
    Opt2 string `json:"opt2"`
    Opt3 string `json:"opt3"`
    Opt4 string `json:"opt4"`
}

type Data struct {
    Title1 `json:"title1"`
    Title2 `json:"title2"`
}

此外,因为title1title2都有相同的字段。您还可以执行以下操作,(playground link
type Title struct {
    Opt1 string `json:"opt1"`
    Opt2 string `json:"opt2"`
    Opt3 string `json:"opt3"`
    Opt4 string `json:"opt4"`
}

type Data struct {
    Title1 Title `json:"title1"`
    Title2 Title `json:"title2"`
}

在Golang社区,这个json-to-go工具非常重要。
json.Unmarshal([]byte(data), Title1)中,使用struct typeTitle1将导致编译错误。第二个参数需要结构类型的指针来解组输入。所以:
// data := Title1{} 
data := Data{}
_ = json.Unmarshal([]byte(input), &data)

最重要的是,不要忽略错误。错误信息会给你方向,让你看看哪里出了什么问题。
if err := json.Unmarshal([]byte(input), &dataOutput); err != nil {
    log.Panic(err)
}

因此,在考虑了上述所有变化之后,一个工作示例是:
package main

import (
    "encoding/json"
    "io/ioutil"
    "log"
)

type Title struct {
    Opt1 string `json:"opt1"`
    Opt2 string `json:"opt2"`
    Opt3 string `json:"opt3"`
    Opt4 string `json:"opt4"`
}

type Data struct {
    Title1 Title `json:"title1"`
    Title2 Title `json:"title2"`
}

func main() {
    // Read from the file
    input, error := ioutil.ReadFile("file.json")
    if error != nil {
        log.Panic(error)
    } else {
        data := Data{}
        if err := json.Unmarshal([]byte(input), &data); err != nil {
            log.Panic(err)
        }
        log.Println("Opt1: " + data.Title1.Opt1)
    }
}

关于json - 如何在Go中解析json?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57062434/

相关文章:

javascript - {"readyState":0 ,"status":0 ,"statusText" :"NetworkError: Failed to execute ' send' on 'XMLHttpRequest' : Failed to load

json - Elm:解码在 JSON 中编码为字符串的 float

string - 在 Golang 中,从 int64 到 string 再到 slice 的转换不起作用

go - golang中如何在函数开始运行时立即执行ticker

inheritance - 组合和多重继承

java - 在java/Android中解析JSON

java - 对于其余请求,验证在 Spring boot 中不起作用

jquery - 解析多级JSON

go - 我似乎无法让 rdkafka 与 confuent-kafka-go 包一起玩

json - 解码到自定义接口(interface)