成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go:終于有了處理未定義字段的實(shí)用方案

開發(fā) 后端
多年來,Go 開發(fā)者一直依賴 JSON 結(jié)構(gòu)標(biāo)簽 omitempty 來解決“字段可能缺失”這一需求。然而omitempty 并不能覆蓋所有場景,而且常常讓人抓狂——到底什么算“空”?定義本就含糊不清。

眾所周知,Go 里沒有 undefined,只有各類型的零值。多年來,Go 開發(fā)者一直依賴 JSON 結(jié)構(gòu)標(biāo)簽 omitempty 來解決“字段可能缺失”這一需求。

然而omitempty 并不能覆蓋所有場景,而且常常讓人抓狂——到底什么算“空”?定義本就含糊不清。

在 編碼(marshal) 時:

  • 切片和 map 只有在為 nil 或長度為 0 時才算空。
  • 指針只有 nil 時為空。
  • 結(jié)構(gòu)體永遠(yuǎn)不算空。
  • 字符串長度為 0 時為空。
  • 其余類型為各自的零值時為空。

而在 解碼(unmarshal) 時……你根本無法區(qū)分:

  • 輸入里根本沒有這個字段,還是該字段存在且值正好是 Go 的零值。
  • omitempty 需要考慮的情況太多,既不方便又容易出錯。

常見變通辦法

社區(qū)常見的權(quán)宜之計(jì)是對“可能缺失”的字段統(tǒng)統(tǒng)用指針類型,并配合 omitempty:

  • 編碼時,nil 字段一定不會寫進(jìn)輸出。
  • 解碼時,字段若為 nil,即可判斷輸入里沒有此字段。

但這并不完美。當(dāng)你需要“可空值”(null 本身就是業(yè)務(wù)允許的合法值)時,一切又回到原點(diǎn):

  • 解碼時無法分辨字段缺失還是值為 null(Go 對應(yīng) nil)。
  • 編碼時若繼續(xù)用 omitempty,那么值為 nil 的字段又會被省略。

此外,大量指針也意味著到處都是判空和解引用,繁瑣且易出錯。

解決方案

隨著 Go 1.24 引入 omitzero 標(biāo)簽,我們終于可以優(yōu)雅地解決這一切。

omitzero 比 omitempty 簡單得多:字段若為零值就被省略。它同樣適用于結(jié)構(gòu)體——當(dāng)且僅當(dāng)其所有字段都是零值時才算零。

舉個例子,想省略零值的 time.Time 字段,如今只需:

type MyStruct struct {  
    SomeTime time.Time `json:",omitzero"`  
}

再也不會輸出 0001-01-01T00:00:00Z 了!不過仍有遺留難題:

  • 編碼時如何處理“可空值”?
  • 如何區(qū)分“零值”與“未定義”?
  • 解碼時如何區(qū)分 null 與字段缺失?

Undefined 包裝類型

得益于 omitzero 對結(jié)構(gòu)體的支持,我們可以設(shè)計(jì)一個通用包裝類型來一次性解決以上問題。思路:利用結(jié)構(gòu)體“零值”+omitzero 標(biāo)簽。

type Undefined[T any] struct {  
    Val     T   // 實(shí)際值  
    Present bool// 標(biāo)記字段是否出現(xiàn)  
}

只要 Present 設(shè)為 true,結(jié)構(gòu)體就不再是零值;由此我們便能確定“字段已出現(xiàn)”。再實(shí)現(xiàn) json.Marshaler 與 json.Unmarshaler 接口,使其按預(yù)期工作:

func (u *Undefined[T]) UnmarshalJSON(data []byte) error {  
    if err := json.Unmarshal(data, &u.Val); err != nil {  
        return fmt.Errorf("Undefined: 反序列化失敗: %w", err)  
    }  
    u.Present = true  
    return nil  
}  

func (u Undefined[T]) MarshalJSON() ([]byte, error) {  
    data, err := json.Marshal(u.Val)  
    if err != nil {  
        return nil, fmt.Errorf("Undefined: 序列化失敗: %w", err)  
    }  
    return data, nil  
}  

// 供 encoding/json 判斷零值  
func (u Undefined[T]) IsZero() bool {  
    return !u.Present  
}
  • 若輸入缺少該字段,UnmarshalJSON 根本不會被調(diào)用,Present 仍為 false → “未定義”。
  • 若字段存在(哪怕值為 null/零值),我們會運(yùn)行 UnmarshalJSON 并把 Present 設(shè)為 true → “已出現(xiàn)”。
  • 編碼時只輸出 Val 本身;若 Present=false,omitzero 會令其整體被省略。
  • IsZero() 讓標(biāo)準(zhǔn)庫更高效地判斷零值。

泛型參數(shù) T 使其能包裝任何類型,一勞永逸。

進(jìn)一步擴(kuò)展

同理也可實(shí)現(xiàn)數(shù)據(jù)庫掃描(sql.Scanner)接口——這樣就能區(qū)分列是否被查詢出來。完整實(shí)現(xiàn)已收錄在 Goyave 框架中,內(nèi)含更多實(shí)用工具與特性。

責(zé)任編輯:趙寧寧 來源: 令飛編程
相關(guān)推薦

2021-12-13 20:09:33

GoElasticsearJava

2009-09-16 13:53:47

WebForm

2013-12-12 14:04:28

C編程語言

2023-11-02 08:43:08

protocgo兼容

2014-03-27 15:01:50

算法C++

2015-07-27 18:23:13

google

2022-11-08 08:29:43

Goslog 庫工具

2021-01-26 10:17:48

智能語音大數(shù)據(jù)機(jī)器學(xué)習(xí)

2021-01-26 16:17:42

人工智能機(jī)器學(xué)習(xí)智能語音

2020-10-08 11:24:04

數(shù)據(jù)分析技術(shù)IT

2013-01-22 10:54:51

HTML5App移動應(yīng)用

2023-12-04 09:37:00

C++靜態(tài)變量

2021-12-06 12:48:40

Gosyncatomic

2021-11-02 22:47:30

微信功能技巧

2021-08-18 15:05:24

區(qū)塊鏈女性金融

2020-08-06 16:55:37

虛擬化底層計(jì)算機(jī)

2024-12-04 07:00:00

2023-10-31 07:40:15

EslintJSHint

2024-07-08 00:00:07

2022-11-02 15:35:35

Condition代碼線程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: www.9191| 成人一区二区三区在线观看 | 国产精品久久久乱弄 | 国产欧美一区二区三区在线看 | 麻豆精品久久久 | www.日韩高清| 国产一区中文 | 久久国产精99精产国高潮 | 亚洲欧美日韩精品久久亚洲区 | 久久久www成人免费精品 | 黄色片在线观看网址 | 婷婷亚洲综合 | 日韩在线播放av | 天天躁日日躁xxxxaaaa | 天天想天天干 | 国产98色在线 | 亚洲精品亚洲人成人网 | 久久精品一区 | 激情的网站 | 一级毛片大全免费播放 | 91欧美精品成人综合在线观看 | 日韩一区二区三区精品 | 欧美中文字幕在线 | 99re视频这里只有精品 | 国产精品免费观看视频 | 国产精品视频入口 | 红色av社区 | 九九爱这里只有精品 | 精品久久久久久亚洲国产800 | 欧洲精品码一区二区三区免费看 | 日韩欧美三级在线 | 99久久婷婷国产亚洲终合精品 | av激情影院 | 久久综合爱 | 在线日韩在线 | 中文字幕久久精品 | 91久色| 久久精品视频免费看 | 亚洲一区中文字幕在线观看 | 亚洲精品久久久久avwww潮水 | 久久久国产精品一区 |