json - golang 结构仅从 json 中部分解码

标签 json go struct unmarshalling

我正在尝试将 json 转换为 golang 嵌套结构。它只是部分工作。大多数字段都不能正确解析,尽管有些可以。为什么不将来自 json 的所有数据都转换为 golang 结构?我的猜测是我的 json 格式和 golang 结构之间有一些错误,但我没有看到它。发帖让其他人关注这个问题。

当我运行程序时,机器 ip 地址被解码,但测试运行 id 却没有。这是我的主要方法的输出:

test run id:
machine ip:172.25.148.39

这是我的 golang 代码:

package main

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

func main() {
    var testRunConfig TestRunConfig
    testRunConfigJson := ReadFile("testrun-config.json")
    err := json.Unmarshal([]byte(testRunConfigJson), &testRunConfig)
    if err != nil {
        HandleError(err)
    }

    println("test run id:" + testRunConfig.Id)
    println("machine ip:" + testRunConfig.Machines[0].IP)
}

//Logs the error, the function and the line number where it was generated
func HandleError(err error) (bool) {
    b := false

    if err != nil {
        // notice that we're using 1, so it will actually log the where
        // the error happened, 0 = this function, we don't want that.
        pc, fn, line, _ := runtime.Caller(1)

        log.Printf("[error] in %s[%s:%d] %v", runtime.FuncForPC(pc).Name(), fn, line, err)
        b = true
        panic(err)
    }

    return b
}


func ReadFile(fileName string) string {
    dat, err := ioutil.ReadFile(fileName)
    HandleError(err)
    return string(dat)
}

//http://json2struct.mervine.net/
type Machine struct {
    IP         string
    Interfaces []Interface
    Containers []Container
    CmdBuffer  bytes.Buffer
}

type InetAddress struct {
    Addr string
    DelayMS  int
}

type Interface struct {
    Name          string
    InetAddresses []InetAddress
}

type Volume struct {
    Localhost string
    Volume    string
}

type NetworkTopology struct {
    Host string
    Port string
}

type Container struct {
    Image           string
    Mem             string
    Cpu             float64
    Disk            string
    Volume          Volume
    NodeId          int
    ServiceType     string
    InstanceId      string
    Port            string
    NetworkTopology []NetworkTopology
    Args            map[string]string

    //"machine" element being a member of a Container is helpful for code flow/logic,
    //but is not required as part of the data model (it's duplicate data).
    //This is why it's private (not capitalized).  Think of it as a "transient" in java.
    machine         Machine
}

type TestRunConfig struct {
    Id       string
    Machines []Machine
}

这是正在转换的 json:

{
  "Id:": "testRunId",
  "Machines": [
    {
      "Ip": "172.25.148.39",
      "Interfaces": [
        {
          "Name": "ems3f0",
          "InetAddresses": [
            {
              "Addr": "10.0.0.x/16",
              "DelayMS": 0
            }
          ]
        },
        {
          "Name": "ems3f1",
          "InetAddresses": [
            {
              "Addr": "10.5.0.x/16",
              "DelayMS": 5
            },
            {
              "Addr": "10.15.0.x/16",
              "DelayMS": 15
            },
            {
              "Addr": "10.25.0.x/16",
              "DelayMS": 25
            }
          ]
        }
      ],
      "Containers": [
        {
          "Image": "docker-core:1",
          "Mem": "20GB",
          "Cpu": 1.0,
          "Disk": "20GB",
          "Volume": {
            "Localhost": "/mnt/md0/${containerId}",
            "Volume": "/root/.btcd${containerId}"
          },
          "NodeId": 0,
          "ServiceType": "core",
          "InstanceId": "core1",
          "Port": "f(nodeid, serviceid, instanceId -> port #)",
          "NetworkTopology": [
            {
              "Host": "ip.address",
              "Port": "some.port"
            }
          ],
          "Args": {
            "database": "${volume}/init-data.csv.tgz",
            "listenPort": "1234",
            "sendPort": "1234"
          }
        },
        {
          "Image": "docker-wallet:1",
          "Mem": "20GB",
          "Cpu": 1.0,
          "Disk": "20GB",
          "Volume": {
            "Localhost": "/mnt/md0/${containerId}",
            "Volume": "/root/.btcd${containerId}"
          },
          "NodeId (cluster)": 0,
          "ServiceType": "wallet",
          "InstanceId": "1...100",
          "Port": "portNum",
          "Args": {
            "Database": "${volume}/init-data.csv.tgz",
            "ListenPort": "1234",
            "SendPort": "1234"
          }
        }
      ]
    }
  ]
}

最佳答案

在您的 JSON 中,您有一个拼写错误(一个额外的冒号)。您将有问题的字段称为 "Id:" 而不是 "Id"。删除 : 代码应该可以工作了!

请注意,您的 NodeId 字段也可能不会填充,因为在 JSON 中,您将其称为 "NodeId (cluster)" 而不是 "NodeId"。 JSON 和 Go 中的字段名称必须完全匹配。如果您想在 JSON 中使用与 Go 中不同的字段名称,请使用 JSON 名称注释您的结构:

type Example struct {
   Name string   `json:"firstName"`
   ...
}

关于json - golang 结构仅从 json 中部分解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46875811/

相关文章:

c - 在 do..while 循环中递增 sscanf() 并将行存储到结构中

java - 使用 JerseyIncation 构建器测试放置格式错误的 json

c++ - C++ 中结构的构造函数导致非零退出代码

objective-c - -[__NSCFDictionary JSONRepresentation] : unrecognized selector

Go 找不到我的本地包

http - Go - 使用负载重定向到特定的 url

git - 除 golang.org 之外的所有源上均出现 "go get"git 错误

声明后更改结构的大小

python - 如何使用python合并包含数组的json对象?

javascript - JSON 化 Blob 文件