Unmarshal JSON with Arbitrary Key/Value Pairs to Struct
Problem
You have a JSON string with a combination of known and unknown fields. You need to parse this JSON and map the known fields to a struct while preserving the unknown fields.
Solution 1: Double Unmarshal
type KnownFields struct { Known1 string Known2 string } type Message struct { Known1 string `json:"known1"` Known2 string `json:"known2"` Unknowns map[string]interface{} `json:"-"` } func ParseMessage(jsonStr string) (*Message, error) { var knownFields KnownFields if err := json.Unmarshal([]byte(jsonStr), &knownFields); err != nil { return nil, err } var m map[string]interface{} if err := json.Unmarshal([]byte(jsonStr), &m); err != nil { return nil, err } delete(m, "known1") delete(m, "known2") return &Message{ Known1: knownFields.Known1, Known2: knownFields.Known2, Unknowns: m, }, nil }
Solution 2: Directly Unmarshal to Map[string]interface{}
type Message map[string]interface{} func ParseMessage(jsonStr string) (*Message, error) { var m Message if err := json.Unmarshal([]byte(jsonStr), &m); err != nil { return nil, err } return &m, nil }
Additional Option: Unmarshal to Interface{}
func ParseMessage(jsonStr string) (interface{}, error) { var m interface{} if err := json.Unmarshal([]byte(jsonStr), &m); err != nil { return nil, err } return m, nil }
The choice between these options depends on your specific requirements. Solution 1 provides a structured Message type that clearly separates known and unknown fields. Solution 2 offers a more flexible approach, allowing you to access all fields as a map. Solution 3 presents a simplified way to unmarshal the JSON into an untyped interface, which you can then handle as needed.
The above is the detailed content of How to Unmarshal JSON with Arbitrary Key/Value Pairs to a Struct in Go?. For more information, please follow other related articles on the PHP Chinese website!