<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
編譯自 Custom JSON Marshalling in Go。
我們知道,通過tag,可以有條件地實現客製化Go JSON序列化的方式,比如json:",omitempty", 當欄位的值為空的時候,我們可以在序列化後的資料中不包含這個值,而json:"-"可以直接不被JSON序列化,如果想被序列化key-,可以設定tag為json:"-,",加個逗號。
如果你為型別實現了MarshalJSON() ([]byte, error)和UnmarshalJSON(b []byte) error方法,那麼這個型別在序列化反序列化時將採用你客製化的方法。
這些都是我們常用的設定技巧。
如果臨時想為一個struct增加一個欄位的話,可以採用本譯文的技巧,臨時建立一個型別,通過嵌入原型別的方式來實現。他和JSON and struct composition in Go一文中介紹的技巧還不一樣(譯文和jsoniter-go擴充套件可以閱讀陶文的Golang 中使用 JSON 的一些小技巧)。JSON and struct composition in Go一文中是通過嵌入的方式建立一個新的型別,你序列化和反序列化的時候需要使用這個新型別,而本譯文中的方法是無痛改變原型別的MarshalJSON方式,採用Alias方式避免遞迴解析,確實是一種非常巧妙的方法。
Go的 encoding/json序列化strcut到JSON資料:
package main import ( "encoding/json" "os" "time" ) type MyUser struct { ID int64 `json:"id"` Name string `json:"name"` LastSeen time.Time `json:"lastSeen"` } func main() { _ = json.NewEncoder(os.Stdout).Encode( &MyUser{1, "Ken", time.Now()}, ) }
{"id":1,"name":"Ken","lastSeen":"2009-11-10T23:00:00Z"}
但是如果我們想改變一個欄位的顯示結果我們要怎麼做呢?例如,我們想把LastSeen顯示為unix時間戳。
最簡單的方式是引入另外一個輔助struct,在MarshalJSON中使用它進行正確的格式化:
func (u *MyUser) MarshalJSON() ([]byte, error) { return json.Marshal(&struct { ID int64 `json:"id"` Name string `json:"name"` LastSeen int64 `json:"lastSeen"` }{ ID: u.ID, Name: u.Name, LastSeen: u.LastSeen.Unix(), }) }
這樣做當然沒有問題,但是如果有很多欄位的話就會很麻煩,如果我們能把原始struct嵌入到新的struct中,並讓它繼承所有不需要改變的欄位就太好了:
func (u *MyUser) MarshalJSON() ([]byte, error) { return json.Marshal(&struct { LastSeen int64 `json:"lastSeen"` *MyUser }{ LastSeen: u.LastSeen.Unix(), MyUser: u, }) }
但是等等,問題是這個輔助struct也會繼承原始struct的MarshalJSON方法,這會導致這個方法進入無限迴圈中,最後堆疊溢位。
解決辦法就是為原始型別起一個別名,別名會有原始struct所有的欄位,但是不會繼承它的方法:
func (u *MyUser) MarshalJSON() ([]byte, error) { type Alias MyUser return json.Marshal(&struct { LastSeen int64 `json:"lastSeen"` *Alias }{ LastSeen: u.LastSeen.Unix(), Alias: (*Alias)(u), }) }
同樣的技術也可以應用於UnmarshalJSON方法:
func (u *MyUser) UnmarshalJSON(data []byte) error { type Alias MyUser aux := &struct { LastSeen int64 `json:"lastSeen"` *Alias }{ Alias: (*Alias)(u), } if err := json.Unmarshal(data, &aux); err != nil { return err } u.LastSeen = time.Unix(aux.LastSeen, 0) return nil }
以上就是自定義Go Json的序列化方法譯文的詳細內容,更多關於Go Json序列化自定義的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45