JSON Unmarshal不适用于由Relect创建的动态结构

问题描述 投票:0回答:2

我正在尝试使用动态创建的结构来解析JSON文件,但是显然我在做错什么。有人可以告诉我们我在做什么错:

https://play.golang.org/p/C2I4Pduduyg

提前感谢。

json go reflection unmarshalling reflect
2个回答
0
投票

reflect.New返回代表指针的值。更改第69行:

fmt.Printf(">>> %v", &parsed)

结果:

>>> <struct { Amqp1 struct { Test string "json:\"test\""; Float float64 "json:\"float\""; Connections []main.Connection "json:\"connections\"" } } Value>

0
投票

我会建议一些不同的东西。我通常避免像瘟疫一样反思。您可以通过简单地为所需的每种配置类型提供结构,然后进行初始的“预解组”来确定您应实际使用的配置类型,从而完成您想做的事情:

package main

import (
    "encoding/json"
    "fmt"
    "os"
)

//Amqp1 config struct
type Amqp1 struct {
    Config struct {
        Test        string       `json:"test,omitempty"`
        Float       float64      `json:"float,omitempty"`
        Connections []Connection `json:"connections,omitempty"`
    } `json:"Amqp1"`
}

//Connection struct
type Connection struct {
    Type string `json:"type"`
    URL  string `json:"url"`
}

//JSONConfigContent json
const JSONConfigContent = `{
    "Amqp1": {
        "test": "woobalooba",
        "float": 5.5,
        "connections": [
            {"type": "test1", "url": "booyaka"},
            {"type": "test2", "url": "foobar"}
        ]
    }
}`

func main() {
    configMap := make(map[string]interface{})
    if err := json.Unmarshal([]byte(JSONConfigContent), &configMap); err != nil {
        fmt.Printf("unable to parse data from provided configuration file: %s\n", err)
        os.Exit(1)
    }

    //get config name
    var configName string
    for cfg := range configMap {
        configName = cfg
        break
    }

    //unmarshal appropriately
    switch configName {
    case "Amqp1":
        fmt.Printf("%s >>\n", configName)
        var amqp1 Amqp1
        if err := json.Unmarshal([]byte(JSONConfigContent), &amqp1); err != nil {
            fmt.Printf("unable to parse data from provided configuration file: %s\n", err)
            os.Exit(1)
        }
        fmt.Printf("Test: %s\n", amqp1.Config.Test)
        fmt.Printf("Float: %v\n", amqp1.Config.Float)
        fmt.Printf("Connections: %#v\n", amqp1.Config.Connections)

    default:
        fmt.Printf("unknown config encountered: %s\n", configName)
        os.Exit(1)
    }
}

最初的“预解组”发生在main()的第二行上,到达了一个普通地图,其中的键是一个字符串,值是interface {},因为您不在乎。您只是在执行此操作以获取配置的实际类型,这是第一个嵌套对象的键。

您也可以run this on playground

© www.soinside.com 2019 - 2024. All rights reserved.