第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

如何將 JSON 對(duì)象數(shù)組轉(zhuǎn)換為 Go 中具有默認(rèn)值的結(jié)構(gòu)數(shù)組?

如何將 JSON 對(duì)象數(shù)組轉(zhuǎn)換為 Go 中具有默認(rèn)值的結(jié)構(gòu)數(shù)組?

Go
桃花長(zhǎng)相依 2021-11-15 15:49:26
我正在開(kāi)發(fā)一個(gè) Go API,它可以接收由 JSON 對(duì)象數(shù)組組成的 POST。POST 的結(jié)構(gòu)類(lèi)似于:[  {    "name":"Las Vegas",    "size":14  },  {    "valid": false,    "name":"Buffalo",    "size":63  }]  假設(shè)我有以下結(jié)構(gòu):type Data {    Valid    bool    Name     string    Size     float64}我想創(chuàng)建一堆Datas 并Valid設(shè)置為true任何時(shí)候它實(shí)際上并未在 JSON 中指定為false. 如果我只做一個(gè),我可以在 Go 中解析 JSON 時(shí)使用如何指定默認(rèn)值,但是對(duì)于未知數(shù)量的它們,我唯一能想到的是:var allMap []map[string]interface{}var structs []Datafor _, item := range allMap {  var data Data  var v interface{}  var ok bool  if v, ok := item["value"]; ok {    data.Valid = v  } else {    data.Valid = true  }  id v, ok := item["name"]; ok {    data.Name = v  }  ...  structs = append(structs, data)}return structs現(xiàn)在我實(shí)際使用的結(jié)構(gòu)有 14 個(gè)字段,其中一些具有我想分配默認(rèn)值的值,其他的可以留空,但所有這些都必須使用這種方法進(jìn)行迭代。有沒(méi)有更好的辦法?
查看完整描述

2 回答

?
九州編程

TA貢獻(xiàn)1785條經(jīng)驗(yàn) 獲得超4個(gè)贊

您可以使用該json.RawMessage類(lèi)型來(lái)推遲解組某些 JSON 文本值。如果您使用這種類(lèi)型,那么 JSON 文本將存儲(chǔ)在其中而無(wú)需解組(因此您可以稍后根據(jù)需要解組此片段)。


因此,在您的情況下,如果您嘗試解組成一個(gè)這樣的切片RawMessage,您可以使用您在問(wèn)題中鏈接的技術(shù),即您可以迭代原始值的切片(每個(gè)值的 JSON 文本Data),創(chuàng)建一個(gè)Datastruct 將您想要的值作為缺失值的默認(rèn)值,并將切片元素解組到這個(gè)準(zhǔn)備好的結(jié)構(gòu)中。就這樣。


它看起來(lái)像這樣:


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上試一試。


注釋/變體


為了提高效率(為了避免復(fù)制結(jié)構(gòu)體),您還allData可以在上面的示例中使成為一個(gè)指針切片,如下所示:


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)

    }

}

如果您想繼續(xù)使用非指針,為了提高效率,您可以在切片元素本身中“準(zhǔn)備”您想要的默認(rèn)值,如下所示:


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)

    }

}


查看完整回答
反對(duì) 回復(fù) 2021-11-15
?
白衣染霜花

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超10個(gè)贊

您可以通過(guò)UnmarshalJSON在您的類(lèi)型上提供一種方法來(lái)使其透明并自動(dòng)工作,即使您的類(lèi)型在結(jié)構(gòu)或切片中找到,您也可以做一個(gè)很好的技巧。


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

}

類(lèi)型的_Data存在只是為了讓我們可以調(diào)用json.Unmarshal(j, &tmp)并獲得原始的未覆蓋行為,而不是調(diào)用UnmarshalJSON我們已經(jīng)在中間的方法。我們可以tmp使用您已經(jīng)鏈接到的技巧設(shè)置默認(rèn)值。然后在解組完成后,我們可以轉(zhuǎn)換tmp為,Data因?yàn)楫吘笵ata和_Data確實(shí)是相同的類(lèi)型。


鑒于這種方法,您可以簡(jiǎn)單地


var structs []Data

err := json.Unmarshal(input, &structs)

(或同樣使用 a json.Decoder)并讓它按照您想要的方式工作。


查看完整回答
反對(duì) 回復(fù) 2021-11-15
  • 2 回答
  • 0 關(guān)注
  • 378 瀏覽
慕課專(zhuān)欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢(xún)優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)