繁体   English   中英

Go是否可以解组地图[string] [] interface {}?

[英]Is Go able to unmarshal to map[string][]interface{}?

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

  • bool,用于JSON布尔值
  • float64,用于JSON数字
  • 字符串,用于JSON字符串-[] interface {},用于JSON数组
  • map [string] interface {},用于JSON对象
  • 对于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)

错误信息:

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

Go encoding/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)
}

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)
}

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

更好的方法是将struct用于主架构,然后使用电子邮件结构的一部分来获取电子邮件实体的数据,以便根据需要从同一实体获取值。 请在下面找到解决方案:

package main

import (
    "fmt"
    "encoding/json"
)

type Data struct{
    IsSchemaConforming bool `json:"isSchemaConforming"`
    SchemaVersion float64 `json:"schemaVersion"`
    EmailEntity []Email `json:"unknown.0"`
}

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

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

    var dynamic Data
    json.Unmarshal([]byte(jsonStr), &dynamic)
    fmt.Printf("%#v", dynamic)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM