使用 JSON 資料通常涉及將其轉換為結構以進行進一步處理。然而,當結構體包含具有影響解組過程的自訂標籤的欄位時,就會出現挑戰。本文示範如何使用 Go 的反射功能處理此類場景。
在這種特殊情況下,目標是將 JSON 資料解組到一個結構體中,其中一個欄位具有標籤表明它應該被視為 JSON 字串。讓我們考慮這個例子:
<code class="go">const data = `{ "I": 3, "S": { "phone": { "sales": "2223334444" } } }` type A struct { I int64 S string `sql:"type:json"` }</code>
在這種情況下,目標是將 JSON 中的「S」欄位作為字串解組到結構體 A 中。
Go 提供了內建的 UnmarshalJSON 方法,允許自訂解組行為。透過建立一個新類型,實作MarshalJSON 和UnmarshalJSON 方法,我們可以達到預期的結果:
<code class="go">import ( "encoding/json" "errors" "log" "fmt" ) // RawString is a raw encoded JSON object. // It implements Marshaler and Unmarshaler and can // be used to delay JSON decoding or precompute a JSON encoding. type RawString string // MarshalJSON returns *m as the JSON encoding of m. func (m *RawString) MarshalJSON() ([]byte, error) { return []byte(*m), nil } // UnmarshalJSON sets *m to a copy of data. func (m *RawString) UnmarshalJSON(data []byte) error { if m == nil { return errors.New("RawString: UnmarshalJSON on nil pointer") } *m += RawString(data) return nil } const data = `{"i": 3, "S": {"phone": {"sales": "2223334444"}}}` type A struct { I int64 S RawString `sql:"type:json"` } func main() { a := A{} err := json.Unmarshal([]byte(data), &a) if err != nil { log.Fatal("Unmarshal failed", err) } fmt.Println("Done", a) }</code>
在此解決方案中,RawString 類型實作MarshalJSON 和UnmarshalJSON 方法來控制JSON 資料的編碼方式和解碼,本質上允許在解組過程中將“S”字段視為字串。
透過利用 Go 的反射功能和自訂解組方法,可以處理複雜的 JSON 解組場景即使欄位具有需要特殊處理的特定標籤。
以上是如何在 Go 中使用自訂欄位標籤解組 JSON 資料?的詳細內容。更多資訊請關注PHP中文網其他相關文章!