簡體   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