Parsing JSON in Go with a required field
I’ve been doing a bit of work with Go recently, in particular writing some code to parse JSON. Here’s an example program that demonstrates what I learnt, where I’m parsing a JSON string as an instance of a Go struct:
package main
import (
"encoding/json"
"fmt"
)
func main() {
parseJson(`{"number_of_sides": 5}`)
parseJson(`{}`)
parseJson(`<number_of_sides>5</number_of_sides>`)
}
func parseJson(jsonString string) {
var shape Shape
fmt.Printf("trying to parse: %s\n", jsonString)
if err := json.Unmarshal([]byte(jsonString), &shape); err != nil {
fmt.Println("cannot parse string as JSON that looks like `Shape`")
} else if shape.Sides == nil {
fmt.Println("JSON did not include a numeric `number_of_sides` field")
} else {
fmt.Printf("shape has %d sides\n", *shape.Sides)
}
fmt.Println("")
}
type Shape struct {
Sides *int `json:"number_of_sides"`
}
The json:
annotation is a Go feature called a “struct tag” which tells the JSON unmarshaller which JSON field to look at.
Required fields in JSON
I want to know if the number_of_sides
field is present with value 0
or missing.
Suppose I define my struct with an int
field:
type Shape struct {
Sides int `json:"number_of_sides"`
}
When I parse a JSON object without number_of_sides
, Go will create a struct Shape{Sides: 0}
using the 0-value.
Suppose I define my struct with a pointer to an int
:
type Shape struct {
Sides *int `json:"number_of_sides"`
}
When I parse a JSON object without number_of_sides
, Go will create a struct Shape{Sides: nil}
using the 0-value for a pointer. I have to remember to get the pointer value later, not the pointer itself.