Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 如何从字符串表示中获取嵌套结构from变量?_Json_Go - Fatal编程技术网

Json 如何从字符串表示中获取嵌套结构from变量?

Json 如何从字符串表示中获取嵌套结构from变量?,json,go,Json,Go,我有一个JSON文件,看起来像下面这样 { "type": "Weekly", "clients": [ "gozo", "dva" ], "sender": "no-reply@flowace.in", "recipients": { "gozo": [ "a@gmail.com", "b@hotmail.com" ], "dv

我有一个JSON文件,看起来像下面这样

{
    "type": "Weekly",
    "clients": [
        "gozo",
        "dva"
    ],
    "sender": "no-reply@flowace.in",
    "recipients": {
        "gozo": [
            "a@gmail.com",
            "b@hotmail.com"
        ],
        "dva": [
            "c@gmail.com",
            "d@hotmail.com"
        ]
    },
    "features": [
        "Top5UsedApps",
        "TimeSpentOnEachL3",
        "NewlyAssignedL3",
        "HoursLogged"
    ],
    "dbCloning": [
        "dva"
    ] 
}
我已经映射了如下结构

type receivers struct {
    Gozo []string `json:"gozo"`
    Dva  []string `json:"dva"`
    // Add more recievers
}

// Config -- The config object parsed from the JSON file
type Config struct {
    ReportType string    `json:"type"`
    Clients    []string  `json:"clients"`
    Sender     string    `json:"sender"`
    Recipients receivers `json:"recipients"`
    Cloning    []string  `json:"dbCloning"`
}
然后在另一个源文件的某个地方,我执行以下操作

func main() {
    conf := LoadConfig(os.Args[1])
    for _, client := range conf.Clients {

        // Use the client variable of some other function calls

        fmt.Println(conf.Recipients[client]) // This will not work
}
现在我的问题是我怎样才能让它工作。我不能直接循环
conf.Recipients

PS:考虑<代码> LoadConfig < /代码>函数解封JSON并返回<代码> CONF对象.< /P>


编辑1:看起来是设计决策错误。现在使用
map[string][]string
的解决方案。但不要将其标记为答案,因为需要知道如何在没有其他选择的情况下轻松地完成此操作。

问题在于,您的类型
接收器不应具有命名字段。它应该是一个
map[string][]字符串

以下是一个工作示例:

package main

import (
    "encoding/json"
    "fmt"
)

type Config struct {
    ReportType string              `json:"type"`
    Clients    []string            `json:"clients"`
    Sender     string              `json:"sender"`
    Recipients map[string][]string `json:"recipients"`
    Cloning    []string            `json:"dbCloning"`
}

var data = []byte(`{
    "type": "Weekly",
    "clients": [
        "gozo",
        "dva"
    ],
    "sender": "no-reply@flowace.in",
    "recipients": {
        "gozo": [
            "a@gmail.com",
            "b@hotmail.com"
        ],
        "dva": [
            "c@gmail.com",
            "d@hotmail.com"
        ]
    },
    "features": [
        "Top5UsedApps",
        "TimeSpentOnEachL3",
        "NewlyAssignedL3",
        "HoursLogged"
    ],
    "dbCloning": [
        "dva"
    ] 
}`)

func main() {
    var conf Config
    json.Unmarshal(data, &conf)

    for _, client := range conf.Clients {
        fmt.Println(conf.Recipients[client])
    }
}
给出输出

[a@gmail.com b@hotmail.com]
[c@gmail.com d@hotmail.com]

问题是您的类型
接收者不应该有命名字段。它应该是一个
map[string][]字符串

以下是一个工作示例:

package main

import (
    "encoding/json"
    "fmt"
)

type Config struct {
    ReportType string              `json:"type"`
    Clients    []string            `json:"clients"`
    Sender     string              `json:"sender"`
    Recipients map[string][]string `json:"recipients"`
    Cloning    []string            `json:"dbCloning"`
}

var data = []byte(`{
    "type": "Weekly",
    "clients": [
        "gozo",
        "dva"
    ],
    "sender": "no-reply@flowace.in",
    "recipients": {
        "gozo": [
            "a@gmail.com",
            "b@hotmail.com"
        ],
        "dva": [
            "c@gmail.com",
            "d@hotmail.com"
        ]
    },
    "features": [
        "Top5UsedApps",
        "TimeSpentOnEachL3",
        "NewlyAssignedL3",
        "HoursLogged"
    ],
    "dbCloning": [
        "dva"
    ] 
}`)

func main() {
    var conf Config
    json.Unmarshal(data, &conf)

    for _, client := range conf.Clients {
        fmt.Println(conf.Recipients[client])
    }
}
给出输出

[a@gmail.com b@hotmail.com]
[c@gmail.com d@hotmail.com]

range子句提供了一种在数组、切片、字符串、映射或通道上迭代的方法。因此,在将struct转换为上述类型之一之前,无法对其进行范围转换

要在结构字段上循环,可以通过为结构创建一个反射值切片来进行反射

package main

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

type receivers struct {
    Gozo []string `json:"gozo"`
    Dva  []string `json:"dva"`
    // Add more recievers
}

// Config -- The config object parsed from the JSON file
type Config struct {
    ReportType string    `json:"type"`
    Clients    []string  `json:"clients"`
    Sender     string    `json:"sender"`
    Recipients receivers `json:"recipients"`
    Cloning    []string  `json:"dbCloning"`
}

var data = []byte(`{
    "type": "Weekly",
    "clients": [
        "gozo",
        "dva"
    ],
    "sender": "no-reply@flowace.in",
    "recipients": {
        "gozo": [
            "a@gmail.com",
            "b@hotmail.com"
        ],
        "dva": [
            "c@gmail.com",
            "d@hotmail.com"
        ]
    },
    "features": [
        "Top5UsedApps",
        "TimeSpentOnEachL3",
        "NewlyAssignedL3",
        "HoursLogged"
    ],
    "dbCloning": [
        "dva"
    ] 
}`)

func main() {
    var conf Config
    if err := json.Unmarshal(data, &conf); err != nil{
        fmt.Println(err)
    }

    v := reflect.ValueOf(conf.Recipients)

    values := make([]interface{}, v.NumField())

    for i := 0; i < v.NumField(); i++ {
        values[i] = v.Field(i).Interface()
    }

    fmt.Println(values)
}
Field
返回结构的第i个字段 v如果v的种类不是Struct或者i超出范围,它就会恐慌

接口以接口{}的形式返回v的当前值

func (v Value) Interface() (i interface{})

range子句提供了一种在数组、切片、字符串、映射或通道上迭代的方法。因此,在将struct转换为上述类型之一之前,无法对其进行范围转换

要在结构字段上循环,可以通过为结构创建一个反射值切片来进行反射

package main

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

type receivers struct {
    Gozo []string `json:"gozo"`
    Dva  []string `json:"dva"`
    // Add more recievers
}

// Config -- The config object parsed from the JSON file
type Config struct {
    ReportType string    `json:"type"`
    Clients    []string  `json:"clients"`
    Sender     string    `json:"sender"`
    Recipients receivers `json:"recipients"`
    Cloning    []string  `json:"dbCloning"`
}

var data = []byte(`{
    "type": "Weekly",
    "clients": [
        "gozo",
        "dva"
    ],
    "sender": "no-reply@flowace.in",
    "recipients": {
        "gozo": [
            "a@gmail.com",
            "b@hotmail.com"
        ],
        "dva": [
            "c@gmail.com",
            "d@hotmail.com"
        ]
    },
    "features": [
        "Top5UsedApps",
        "TimeSpentOnEachL3",
        "NewlyAssignedL3",
        "HoursLogged"
    ],
    "dbCloning": [
        "dva"
    ] 
}`)

func main() {
    var conf Config
    if err := json.Unmarshal(data, &conf); err != nil{
        fmt.Println(err)
    }

    v := reflect.ValueOf(conf.Recipients)

    values := make([]interface{}, v.NumField())

    for i := 0; i < v.NumField(); i++ {
        values[i] = v.Field(i).Interface()
    }

    fmt.Println(values)
}
Field
返回结构的第i个字段 v如果v的种类不是Struct或者i超出范围,它就会恐慌

接口以接口{}的形式返回v的当前值

func (v Value) Interface() (i interface{})

你不能使用
[]
操作符访问你的
接收者
结构。是的,我知道。但是我怎么能用其他方式来做呢。想法是客户端需要是动态的,因为接收者不是一个片,而是一个结构。如果它应该是动态的,映射就很好了,如果您希望它能够在不更改代码的情况下添加新的客户端,那么就不需要为此定义类型。见下面我的答案。你不能使用
[]
操作符访问你的
接收器
结构。是的,我知道。但我怎么能用其他方式来做呢。想法是客户端需要是动态的,因为接收器不是一个片,它是一个结构。如果它应该是动态的,映射会很好,如果您希望它能够在不更改代码的情况下添加新的客户端,那么就不需要为此定义类型。见下面我的答案。