Json 如何从字符串表示中获取嵌套结构from变量?
我有一个JSON文件,看起来像下面这样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
{
"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{})
你不能使用[]
操作符访问你的接收者
结构。是的,我知道。但是我怎么能用其他方式来做呢。想法是客户端需要是动态的,因为接收者不是一个片,而是一个结构。如果它应该是动态的,映射就很好了,如果您希望它能够在不更改代码的情况下添加新的客户端,那么就不需要为此定义类型。见下面我的答案。你不能使用[]
操作符访问你的接收器
结构。是的,我知道。但我怎么能用其他方式来做呢。想法是客户端需要是动态的,因为接收器不是一个片,它是一个结构。如果它应该是动态的,映射会很好,如果您希望它能够在不更改代码的情况下添加新的客户端,那么就不需要为此定义类型。见下面我的答案。