将json字符串解组为具有struct本身的一个元素的结构

UDB*_*UDB 0 json struct go

我是初学者并试图解组以下json字符串

[{
    "db": {
        "url": "mongodb://localhost",
        "port": "27000",
        "uname": "",
        "pass": "",
        "authdb": "",
        "replicas": [
            {
                "rs01": {
                    "url":"mongodb://localhost",
                    "port": "27001",
                    "uname": "",
                    "pass": "",
                    "authdb": ""
                }
            },
            {
                "rs02": {
                    "url":"mongodb://localhost",
                    "port": "27002",
                    "uname": "",
                    "pass": "",
                    "authdb": ""
                }
            }
        ]
    }
}]
Run Code Online (Sandbox Code Playgroud)

这是结构

type DBS struct {
    URL      string `json:url`
    Port     string `json:port`
    Uname    string `json:uname`
    Pass     string `json:pass`
    Authdb   string `json:authdb`
    Replicas []DBS   `json:replicas`
}
Run Code Online (Sandbox Code Playgroud)

这是功能

func loadConfigs() []DBS {
    var config []DBS
    raw, err := ioutil.ReadFile("./config.json")
    if err != nil {
        fmt.Println(err.Error())
        os.Exit(1)
    }

    json.Unmarshal(raw, &config)
    return config
}
Run Code Online (Sandbox Code Playgroud)

该功能正在返回

{     []}
Run Code Online (Sandbox Code Playgroud)

icz*_*cza 5

您的JSON输入不是一个片段DBS,因为有另一个JSON对象包装器,并且DBS属于该属性的值"db".

更深入,这"replicaps"是一个JSON数组,对象包含不同的键,它们的值可以表示DBS.

因此,要完整地描述您的JSON,您需要某种"动态"类型.例如,地图就是这样的动态类型.

因此,您的原始JSON输入可以使用以下类型进行完全建模:[]map[string]DBS.它是一片地图,因为你的JSON输入包含一个JSON数组.map键可以为任何属性名称建模,值是由DBSstruct 建模的JSON对象.

请参阅此示例,该示例完全解析JSON输入:

type DBS struct {
    URL      string           `json:"url"`
    Port     string           `json:"port"`
    Uname    string           `json:"uname"`
    Pass     string           `json:"pass"`
    Authdb   string           `json:"authdb"`
    Replicas []map[string]DBS `json:"replicas"`
}

func main() {
    var dbs []map[string]DBS
    if err := json.Unmarshal([]byte(src), &dbs); err != nil {
        panic(err)
    }
    fmt.Printf("%+v", dbs)
}
Run Code Online (Sandbox Code Playgroud)

请注意正确的标记语法(例如json:"url").

输出(在Go Playground上试试):

[map[db:{URL:mongodb://localhost Port:27000 Uname: Pass: Authdb: Replicas:[map[rs01:{URL:mongodb://localhost Port:27001 Uname: Pass: Authdb: Replicas:[]}] map[rs02:{URL:mongodb://localhost Port:27002 Uname: Pass: Authdb: Replicas:[]}]]}]]

请注意,您可以进一步建模第一个级别"db",我们可以切换到指针(我在第一个示例中使用了非指针,因此打印结果是可读的):

type DBReplicated struct {
    DB *DBS `json:"db"`
}

type DBS struct {
    URL      string            `json:"url"`
    Port     string            `json:"port"`
    Uname    string            `json:"uname"`
    Pass     string            `json:"pass"`
    Authdb   string            `json:"authdb"`
    Replicas []map[string]*DBS `json:"replicas"`
}

func main() {
    var dbs []*DBReplicated
    if err := json.Unmarshal([]byte(src), &dbs); err != nil {
        panic(err)
    }

    db := dbs[0].DB
    fmt.Printf("%+v\n", db)
    for _, dbs := range db.Replicas {
        for name, replica := range dbs {
            fmt.Printf("%s: %+v\n", name, replica)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出(在Go Playground上试试):

&{URL:mongodb://localhost Port:27000 Uname: Pass: Authdb: Replicas:[map[rs01:0x10538200] map[rs02:0x10538240]]}
rs01: &{URL:mongodb://localhost Port:27001 Uname: Pass: Authdb: Replicas:[]}
rs02: &{URL:mongodb://localhost Port:27002 Uname: Pass: Authdb: Replicas:[]}
Run Code Online (Sandbox Code Playgroud)