2 回答
TA貢獻1785條經驗 獲得超4個贊
您可以使用該json.RawMessage類型來推遲解組某些 JSON 文本值。如果您使用這種類型,那么 JSON 文本將存儲在其中而無需解組(因此您可以稍后根據需要解組此片段)。
因此,在您的情況下,如果您嘗試解組成一個這樣的切片RawMessage,您可以使用您在問題中鏈接的技術,即您可以迭代原始值的切片(每個值的 JSON 文本Data),創建一個Datastruct 將您想要的值作為缺失值的默認值,并將切片元素解組到這個準備好的結構中。就這樣。
它看起來像這樣:
allJson := []json.RawMessage{}
if err := json.Unmarshal(src, &allJson); err != nil {
panic(err)
}
allData := make([]Data, len(allJson))
for i, v := range allJson {
// Here create your Data with default values
allData[i] = Data{Valid: true}
if err := json.Unmarshal(v, &allData[i]); err != nil {
panic(err)
}
}
在Go Playground上試一試。
注釋/變體
為了提高效率(為了避免復制結構體),您還allData可以在上面的示例中使成為一個指針切片,如下所示:
allData := make([]*Data, len(allJson))
for i, v := range allJson {
// Here create your Data with default values
allData[i] = &Data{Valid: true}
if err := json.Unmarshal(v, allData[i]); err != nil {
panic(err)
}
}
如果您想繼續使用非指針,為了提高效率,您可以在切片元素本身中“準備”您想要的默認值,如下所示:
allData := make([]Data, len(allJson))
for i, v := range allJson {
// Here set your default values in the slice elements
// Only set those which defer from the zero values:
allData[i].Valid = true
if err := json.Unmarshal(v, &allData[i]); err != nil {
panic(err)
}
}
TA貢獻1796條經驗 獲得超10個贊
您可以通過UnmarshalJSON在您的類型上提供一種方法來使其透明并自動工作,即使您的類型在結構或切片中找到,您也可以做一個很好的技巧。
func (d *Data) UnmarshalJSON(j []byte) error {
type _Data Data // Dummy type to avoid infinite recursion in UnmarshalJSON
tmp := _Data{ // Set defaults here
Valid: true,
}
err := json.Unmarshal(j, &tmp)
if err != nil {
return err
}
*d = Data(tmp)
return nil
}
類型的_Data存在只是為了讓我們可以調用json.Unmarshal(j, &tmp)并獲得原始的未覆蓋行為,而不是調用UnmarshalJSON我們已經在中間的方法。我們可以tmp使用您已經鏈接到的技巧設置默認值。然后在解組完成后,我們可以轉換tmp為,Data因為畢竟Data和_Data確實是相同的類型。
鑒于這種方法,您可以簡單地
var structs []Data
err := json.Unmarshal(input, &structs)
(或同樣使用 a json.Decoder)并讓它按照您想要的方式工作。
- 2 回答
- 0 關注
- 416 瀏覽
添加回答
舉報
