繁体   English   中英

在切片中解组 2 个不同的结构

[英]Unmarshal 2 different structs in a slice

我的输入 json 数据是这样的(无法更改,来自外部资源):

[{
   "Url": "test.url",
   "Name": "testname"
},{ 
   "FormName": "Test - 2018",
   "FormNumber": 43,
   "FormSlug": "test-2018"
}]

我有两个结构将始终匹配数组中的数据:

type UrlData struct{
  "Url"  string `json:Url` 
  "Name" string `json:Name` 
}

type FormData struct{
  "FormName"  string `json:FormName` 
  "FormNumber" string `json:FormNumber` 
  "FormSlug" string `json:FormSlug`
}

显然,下面的代码不起作用,但是否有可能在顶层(或其他)声明这样的东西:

type ParallelData [
 urlData UrlData
 formData FormData
]

使用两步过程进行解组。 首先,解组任意 JSON 的列表,然后将该列表的第一个和第二个元素解组为各自的类型。

您可以在名为 UnmarshalJSON 的方法中实现该逻辑,从而实现json.Unmarshaler 接口 这将为您提供您正在寻找的化合物类型:

type ParallelData struct {
    UrlData  UrlData
    FormData FormData
}

// UnmarshalJSON implements json.Unmarshaler.
func (p *ParallelData) UnmarshalJSON(b []byte) error {
    var records []json.RawMessage
    if err := json.Unmarshal(b, &records); err != nil {
        return err
    }

    if len(records) < 2 {
        return errors.New("short JSON array")
    }

    if err := json.Unmarshal(records[0], &p.UrlData); err != nil {
        return err
    }

    if err := json.Unmarshal(records[1], &p.FormData); err != nil {
        return err
    }

    return nil
}

在操场上试试: https : //play.golang.org/p/QMn_rbJj-P-

我认为彼得的回答很棒。

选项1:

type ParallelData [
 urlData UrlData
 formData FormData
]

如果您需要上述结构,则可以将其定义为

type UrlData struct {
    Url  string `json:"Url,omitempty"`
    Name string `json:"Name,omitempty"`
}
type FormData struct {
    FormName   string `json:"FormName,omitempty"`
    FormNumber string `json:"FormNumber,omitempty"`
    FormSlug   string `json:"FormSlug,omitempty"`
}
type ParallelData struct {
    UrlData  UrlData  `json:"UrlData,omitempty"`
    FormData FormData `json:"FormData,omitempty"`
}

在这种情况下,您的 json 将如下所示

[  
   {  
      "UrlData":{  
         "Url":"test.url",
         "Name":"testname"
      }
   },
   {  
      "FormData":{  
         "FormName":"Test - 2018",
         "FormNumber":"43",
         "FormSlug":"test-2018"
      }
   }
]

选项 2:

您提供了以下 json:

[  
   {  
      "Url":"test.url",
      "Name":"testname"
   },
   {  
      "FormName":"Test - 2018",
      "FormNumber":43,
      "FormSlug":"test-2018"
   }
]

如果您的 json 真的看起来像,那么您可以使用以下struct

type UrlData struct {
    Url  string `json:Url`
    Name string `json:Name`
}

type FormData struct {
    FormName   string `json:FormName`
    FormNumber int    `json:FormNumber`
    FormSlug   string `json:FormSlug`
}

type ParallelData struct {
    UrlData
    FormData
}

对于这两个选项,您可以像这样解组您的 json

var parallelData []ParallelData
err := json.Unmarshal([]byte(str), &parallelData)
if err != nil {
    panic(err)
}
fmt.Println(parallelData)

操场上查看选项 1

操场上查看选项 2

您可以解组到map[string]interface{}例如:

type ParallelData map[string]interface{}

func main() {
    textBytes := []byte(`[
    {
      "Url": "test.url",
      "Name": "testname" 
    },
    {
      "FormName": "Test - 2018",
      "FormNumber": 43,
      "FormSlug": "test-2018"
    }]`)
    var acc []ParallelData
    json.Unmarshal(textBytes, &acc)

    fmt.Printf("%+v", acc)
}

输出:

=> [map[Url:test.url Name:testname] map[FormName:Test - 2018 FormNumber:43 FormSlug:test-2018]]

操场

暂无
暂无

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

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