package main import ( "encoding/json" "log" "strconv" ) func main() { //unmarshalIdealData() // unmarshalRealWorldData() // unmarshalBoth() } // In an ideal world all data is consistent. idealData is an example of some // json (it represents an event) var idealData = []byte(` { "name": "event name", "id": 1 } `) // IdealEvent is a struct that we can use to unmarshal the data into for using // in bookie type IdealEvent struct { Name string `json:"name"` ID int `json:"id"` } // unmarshalIdealData unmarshals some data in an ideal world func unmarshalIdealData() { var event IdealEvent err := json.Unmarshal(idealData, &event) log.Println(err) log.Println(event) } // In the real world, this aren't always quite so simple. Sometimes things come // in an incorrect format var realWorldData = []byte(` { "name": "event name", "id": "1" } `) // unmarshalRealWorldData unmarshals some incorrectly formatted data. func unmarshalRealWorldData() { var event IdealEvent err := json.Unmarshal(realWorldData, &event) log.Println(err) log.Println(event) } // in golang you can define a new type to handle this type intSometimesString int // RealWorldEvent represents an event that we often see delivered from a feed // where the id is often delivered as an int or a string, for example: type RealWorldEvent struct { Name string `json:"name"` ID intSometimesString `json:"id"` } // UnmarshalJSON is a custom unmarshaller for the intSometimesString type func (ri *intSometimesString) UnmarshalJSON(buf []byte) (err error) { var i int var s string // Check to see if string - if it is, unmarshal and convert to an integer if buf[0] == '"' { if err = json.Unmarshal(buf, &s); err != nil { return err } if s == "" { s = "0" } if i, err = strconv.Atoi(s); err != nil { return err } } else { // otherwise we expect it is an integer if err = json.Unmarshal(buf, &i); err != nil { return err } } *ri = intSometimesString(i) return nil } func unmarshalBoth() { var event RealWorldEvent err := json.Unmarshal(realWorldData, &event) log.Println(err) log.Println(event) err = json.Unmarshal(idealData, &event) log.Println(err) log.Println(event) }