Go 能够解组到 map[string][]interface{} 吗?

Sum*_* Ji 2 json go unmarshalling

目前,我尝试将 JSON 解析为 map[string][]interface{},但解组返回错误。根据(https://golang.org/pkg/encoding/json/),要将 JSON 解组为接口值,Unmarshal 将以下内容之一存储在接口值中:

  • bool,用于 JSON 布尔值
  • float64,用于 JSON 数字
  • string,对于 JSON 字符串 -[]interface{},对于 JSON 数组
  • map[string]interface{},用于 JSON 对象
  • nil 表示 JSON null

我想知道golang是否能够解组map[string][]interface{}。以下是代码片段。我是 Golang 新手,提前感谢您的帮助。

// emailsStr looks like "{"isSchemaConforming":true,"schemaVersion":0,"unknown.0":[{"email_address":"test1@uber.com"},{"email_address":"test2@uber.com"}]}"

emailsRaw := make(map[string][]*entities.Email)
err := json.Unmarshal([]byte(emailsStr), &emailsRaw)
Run Code Online (Sandbox Code Playgroud)

错误信息:

&json.UnmarshalTypeError{值:“number”,类型:(*reflect.rtype)(0x151c7a0),偏移量:44,结构体:“”,字段:“”}

wgo*_*l01 5

Goencoding/json包只会动态解组到map[string]interface{}. 从那里,您将需要使用类型断言和转换来提取您想要的值,如下所示:

func main() {
    jsonStr := `{"isSchemaConforming":true,"schemaVersion":0,"unknown.0":[{"email_address":"test1@uber.com"},{"email_address":"test2@uber.com"}]}`

    dynamic := make(map[string]interface{})
    json.Unmarshal([]byte(jsonStr), &dynamic)

    firstEmail := dynamic["unknown.0"].([]interface{})[0].(map[string]interface{})["email_address"]

    fmt.Println(firstEmail)
}
Run Code Online (Sandbox Code Playgroud)

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

每次,Go 的.(<type>)运算符都用于断言动态值并将其转换为特定类型。如果运行时发生错误类型(例如 的内容unknown.0不是 JSON 对象数组),此特定代码将会出现错误。

在 Go 中执行此操作的更惯用(且更可靠)的方法是使用标签注释几个结构体json:""encoding/json对其进行解组。这避免了所有令人讨厌的脆性.([]interface{})铸造:

type Email struct {
    Email string `json:"email_address"`
}

type EmailsList struct {
    IsSchemaConforming bool `json:"isSchemaConforming"`
    SchemaVersion      int  `json:"schemaVersion"`
    Emails []Email `json:"unknown.0"`
}

func main() {
    jsonStr := `{"isSchemaConforming":true,"schemaVersion":0,"unknown.0":[{"email_address":"test1@uber.com"},{"email_address":"test2@uber.com"}]}`

    emails := EmailsList{}
    json.Unmarshal([]byte(jsonStr), &emails)

    fmt.Printf("%+v\n", emails)
}
Run Code Online (Sandbox Code Playgroud)

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