Unmarshaling JSON with Custom Tag Handling
When attempting to unmarshal JSON into a struct, it can be necessary to handle fields with custom tags differently. This article explores an issue where a field in a struct has a tag indicating that it should be unmarshaled as a string.
Problem:
Consider a JSON string and a corresponding struct:
<code class="json">{ "I": 3, "S": { "phone": { "sales": "2223334444" } } }</code>
<code class="go">type A struct { I int64 S string `sql:"type:json"` }</code>
The goal is to unmarshal the "S" field as a string, rather than a struct.
Solution:
Using Marshaler/Unmarshaler Interface:
Go provides a way to override the default JSON marshaling and unmarshaling behavior by implementing the Marshaler and Unmarshaler interfaces for a custom type. In this case, create a new type called RawString and implement these functions:
<code class="go">type RawString string func (m *RawString) MarshalJSON() ([]byte, error) { return []byte(*m), nil } func (m *RawString) UnmarshalJSON(data []byte) error { if m == nil { return errors.New("RawString: UnmarshalJSON on nil pointer") } *m += RawString(data) return nil }</code>
Applying to the Struct:
Modify the A struct to use the RawString type for the "S" field:
<code class="go">type A struct { I int64 S RawString `sql:"type:json"` }</code>
With this implementation, when JSON is unmarshaled into an A struct, the "S" field will be unmarshaled as a string, preserving its original JSON representation.
Example Usage:
<code class="go">const data = `{"i":3, "S":{"phone": {"sales": "2223334444"}}}` func main() { a := A{} err := json.Unmarshal([]byte(data), &a) if err != nil { log.Fatal("Unmarshal failed:", err) } fmt.Println("Done", a) }</code>
Output:
<code class="text">Done {3 {"phone": {"sales": "2223334444"}}}</code>
The above is the detailed content of How to Unmarshal JSON with Custom Tag Handling for String Representation?. For more information, please follow other related articles on the PHP Chinese website!