使用自訂 MarshalJSON() 方法嵌入結構的慣用方式
鑑於下面的結構,我們可以輕鬆地將 Employee 結構編組為JSON,如下所示預期:
type Person struct { Name string `json:"name"` } type Employee struct { *Person JobRole string `json:"jobRole"` }
但是,當嵌入結構有一個自定義的MarshalJSON() 方法,它破壞了編組過程:
func (p *Person) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Name string `json:"name"` }{ Name: strings.ToUpper(p.Name), }) }
這是因為嵌入的Person 結構實作了MarshalJSON() 函數,該函數優先於Employee 結構自己的MarshalJSON() 方法。
所需的輸出是正常對 Employee 欄位進行編碼,同時遵循 Person 的 MarshalJSON() 方法進行編組它的領域。但是,在 Employee 中加入 MarshalJSON() 方法需要知道嵌入類型也實作了 MarshalJSON(),這可能很脆弱。
要解決這個問題,我們可以使用不同的方法:
建立一個新型別Name 來代表Person name:
type Name string
在Name 上實作MarshalJSON()來自訂其編碼:
func (n Name) MarshalJSON() ([]byte, error) { return json.Marshal(strings.ToUpper(string(n))) }
修改Person 結構以使用Name而不是string:
type Person struct { Name Name `json:"name"` }
此方法允許我們自取定義Person 名稱的編碼,而無需在Employee 結構上使用MarshalJSON() 方法。
或者,如果我們想要更通用地實現這一點,我們需要在外部類型上實作 MarshalJSON。內部類型上的方法被提升為外部類型,因此我們可以呼叫內部類型的 MarshalJSON 方法,將其輸出解組為像 map[string]interface{} 這樣的通用結構,並新增我們自己的欄位。但是,這可能會產生更改最終輸出欄位的順序的副作用。
以上是如何在 Go 中慣用地使用自訂「MarshalJSON()」方法嵌入結構?的詳細內容。更多資訊請關注PHP中文網其他相關文章!