When unmarshalling json into a struct, I'd like to look at the struct (or any other meta data vehicle) to know the whether a json value was provided in the json input or if a json value was omitted from the json input. Consider this code as an example:
package main
import (
"encoding/json"
"log"
)
type Person struct {
Name string `json:"name"`
Grades []Grade `json:"grades"`
}
type Grade struct {
Year int `json:"year"`
Grade int `json:"grade"`
}
func main() {
jsonString := `{"name":"john","grades":[{"year":1998,"grade":0},{"year":1999}]}`
person := Person{}
_ = json.Unmarshal([]byte(jsonString),&person)
log.Println(person)
}
The log prints {john [{1998 0} {1999 0}]}
. What is idiomatic way in Go to know that the zero of 1998 0
was explicitly declared in the JSON string while the zero of 1999 0
was the default zero when initializing the struct Grade
?
The reason I want to know this difference is because I want to use this struct to create an SQL statement that updates the table field t_grade.grade = ?
if and only if the zero was explicitly provided by the json string. Also note that t_grade.grade
in the database is not-nullable.
I am currently using a hack where my grade struct looks like this:
type Grade struct {
Year *int `json:"year"`
Grade *int `json:"grade"`
}
So if the JSON string does not provide a value, then the grade field will be null. Otherwise, the grade field will hold a pointer to a value.
But I'm sure there's a better and idiomatic way to do this?