Marshaling and Unmarshalling JSON Without Stack Overflow
In JSON encoding, calling json.Unmarshal within the UnmarshalJSON method can lead to a stack overflow. This issue arises because the decoder continuously searches for a custom UnmarshalJSON implementation, which in this case is being repeatedly called.
To avoid this, a common solution is to create a new type using the type keyword. This new type effectively serves as a wrapper for the original type. By converting the original value to the new type and passing it to json.Unmarshal, the stack overflow can be prevented.
This approach is efficient as type conversion does not change the representation of the data. As per the Go specification, non-numeric type conversions only modify the type without altering the underlying representation.
In the following example, a Person type is defined with a numeric Age field. A custom UnmarshalJSON method ensures that the age is never negative:
type Person struct { Name string `json:"name"` Age int `json:"age"` } func (p *Person) UnmarshalJSON(data []byte) error { type person2 Person if err := json.Unmarshal(data, (*person2)(p)); err != nil { return err } // Post-processing after unmarshaling if p.Age < 0 { p.Age = 0 } return nil }
This technique can also be applied to custom marshalling (MarshalJSON) methods to perform pre-processing before data serialization.
Remember, when defining a String() method for custom text representation, it's essential to distinguish between using t and *t to avoid inadvertently modifying the default string representation.
The above is the detailed content of How to Avoid Stack Overflow When Marshaling and Unmarshaling JSON in Go?. For more information, please follow other related articles on the PHP Chinese website!