doushenyu2537 2017-10-22 15:25
浏览 31
已采纳

golang结构仅部分从json解组

I am trying to convert json into a golang nested struct. It is only partially working. Most fields do not parse correctly, although some do. Why doesn't all the data from json get converted into a golang struct? My guess is that I have some mistake between my json format and the golang struct, but I don't see it. Posting to get some other eyes on the problem.

When I run the program, the machine ip address is unmarshalled, but the test run id is not. Here is the output from my main method:

test run id:
machine ip:172.25.148.39

Here is my golang code:

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
}

And here is the json being converted:

{
  "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"
          }
        }
      ]
    }
  ]
}
  • 写回答

1条回答 默认 最新

  • dongweicha6077 2017-10-22 15:46
    关注

    In your JSON, you have a typo (an extra colon). You call the field in question "Id:" instead of "Id". Remove the : and the code should work!

    Note that your NodeId field will also likely not populate, because in the JSON, you call it "NodeId (cluster)" instead of "NodeId". The field names must match exactly in JSON and Go. If you want to use different field names in JSON than in Go, annotate your struct with the JSON names:

    type Example struct {
       Name string   `json:"firstName"`
       ...
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100