usage
Friends who are familiar with Golang must be familiar with the conversion between json and struct. In order to decouple the structure in the code from the json data, we usually add explanations after the field type of the structure. For example, when representing an address, the json data is as follows.
{ "street": "200 Larkin St", "city": "San Francisco", "state": "CA", "zipcode": "94102" }
The corresponding Golang structure representation may look like this
type address struct { Street string `json:"street"` // street Ste string `json:"suite"` // Unit (cannot exist) City string `json:"city"` // City State string `json:"state"` // State/Province Zipcode string `json:"zipcode"` // post code}
In this way, no matter how the variables in the code change, we can successfully parse the json data and obtain the correct information of the streets, cities, etc. So far, everything is normal. But if we want to restore the address structure to json format, the problem arises. For example, we use the following code to read the address json, and then process it according to the business logic and restore it to normal json and print it out.
func main() { data := `{ "street": "200 Larkin St", "city": "San Francisco", "state": "CA", "zipcode": "94102" }` addr := new(address) ([]byte(data), &addr) // I processed the addr variable... addressBytes, _ := (addr, "", " ") ("%s\n", string(addressBytes)) }
The output of this code is
{ "street": "200 Larkin St", "suite": "", "city": "San Francisco", "state": "CA", "zipcode": "94102" }
There is an additional line "suite": "", and this information is not available in the original json data (in the United States address, if it is not a group rental apartment or a shared office building, it is normal for the suite to not exist. It is enough for people to directly use the street number to represent the address). But what we would rather be output when an address has a suite number, and if the suite does not exist, it will not be output. Fortunately, we can add the omitempty keyword to the structure definition of Golang to indicate that if this information is not provided, do not include its default value when serialized into json. With a slight modification, the address structure becomes
type address struct { Street string `json:"street"` Ste string `json:"suite,omitempty"` City string `json:"city"` State string `json:"state"` Zipcode string `json:"zipcode"` }
Re-run and you will get the correct results.
trap
While bringing convenience, there are also some small traps when using omitempty. One is that the keyword cannot ignore nested structures. Let’s talk about the address type. This time we want to add a new field to the address structure to represent the latitude and longitude. If there is no relevant data, it can be ignored for the time being. The new struct definition is as follows
type address struct { Street string `json:"street"` Ste string `json:"suite,omitempty"` City string `json:"city"` State string `json:"state"` Zipcode string `json:"zipcode"` Coordinate coordinate `json:"coordinate,omitempty"` } type coordinate struct { Lat float64 `json:"latitude"` Lng float64 `json:"longitude"` }
Read the original address data and serialize the output after processing. We will find that even if the omitempty keyword is added, the output json still has an empty coordinate information.
{ "street": "200 Larkin St", "city": "San Francisco", "state": "CA", "zipcode": "94102", "coordinate": { "latitude": 0, "longitude": 0 } }
In order to achieve the effect we want, we can define the coordinates as pointer type, so that Golang can know what the "null value" of a pointer is. Otherwise, facing a structure we customize, Golang cannot guess the null value we want. So the following structure definition is
type address struct { Street string `json:"street"` Ste string `json:"suite,omitempty"` City string `json:"city"` State string `json:"state"` Zipcode string `json:"zipcode"` Coordinate *coordinate `json:"coordinate,omitempty"` } type coordinate struct { Lat float64 `json:"latitude"` Lng float64 `json:"longitude"` }
The corresponding output is
{ "street": "200 Larkin St", "city": "San Francisco", "state": "CA", "zipcode": "94102" }
Another "trap" is that for a field defined with omitempty, if the value assigned to it is exactly equal to the default null value, the field will not be output after being converted to json. For example, the latitude and longitude coordinate structure defined above, if we add both fields of latitude and longitude, omitempty
type coordinate struct { Lat float64 `json:"latitude,omitempty"` Lng float64 `json:"longitude,omitempty"` }
Then we were very interested in the "original coordinates" of the Gulf of Guinea in Africa, so we wrote the following code
func main() { cData := `{ "latitude": 0.0, "longitude": 0.0 }` c := new(coordinate) ([]byte(cData), &c) // Specific processing logic... coordinateBytes, _ := (c, "", " ") ("%s\n", string(coordinateBytes)) }
Finally we got one
{}
This coordinate disappears! But our idea is that if a location has no latitude and longitude information, it will be dangling, which is no problem, but for the "original coordinates", we are still ignored if we know exactly its latitude and longitude. The correct way to write it is to change the definition in the structure to a pointer
type coordinate struct { Lat *float64 `json:"latitude,omitempty"` Lng *float64 `json:"longitude,omitempty"` }
In this way, the null value will change from 0.0 of float64 to nil of pointer type, and we can see the correct latitude and longitude output.
{ "latitude": 0, "longitude": 0 }
. The address used as an example in this article is the address of the Asian Art Museum in San Francisco. It has rich collections and can be seen from the Xia, Shang and Zhou dynasties to the Ming and Qing dynasties. I first visited it a few years ago and I liked it very much and was deeply impressed.
This is the introduction to this article about the specific implementation of the omitempty keyword in Golang. For more related Golang omitempty content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!