当前位置:网站首页>A brief explanation of golang's keyword "competence"

A brief explanation of golang's keyword "competence"

2022-04-23 19:21:00 Handsome that handsome

usage
be familiar with Golang Friends of json and struct The transition between must be no stranger , In order to compare the structure in the code with json Data decoupling , Usually we'll be in the... Of the structure field Type followed by explanation , For example, when representing an address , json The data is shown below

{
    
    "street": "200 Larkin St",
    "city": "San Francisco",
    "state": "CA",
    "zipcode": "94102"
}

Corresponding to that Golang The structure representation is defined as follows

type address struct {
    
	Street  string `json:"street"`  //  The street 
	Ste     string `json:"suite"`   //  unit ( Can not exist )
	City    string `json:"city"`    //  City 
	State   string `json:"state"`   //  state / province 
	Zipcode string `json:"zipcode"` //  Zip code 
}

So no matter how the variables in the code change , We can all succeed in json The data is parsed out , Get the right Street , City and other information , So far, everything's ok . But if we want to restore the address structure to json When the format , Here's the problem . For example, we read the address with the following code json , Then it is processed according to the business logic and returned to normal json Print out

func main() {
    
  data := `{ "street": "200 Larkin St", "city": "San Francisco", "state": "CA", "zipcode": "94102" }`
	addr := new(address)
	json.Unmarshal([]byte(data), &addr)

        //  Dealt with it  addr  Variable ...

	addressBytes, _ := json.MarshalIndent(addr, "", " ")
	fmt.Printf("%s\n", string(addressBytes))
}

You can get the running results

{
    
    "street": "200 Larkin St",
    "suite": "",
    "city": "San Francisco",
    "state": "CA",
    "zipcode": "94102"
}

One more line “suite”: “”, , And this message is in the original json There is nothing in the data ( In the address of the United States , If it's not a group apartment or shared office building , suite It's normal that this one doesn't exist , It's enough for people to express their address directly by street number ), But what we want more is , There are... In one address suite When the number is output , non-existent suite No output when , Fortunately, , We can do it in Golang Add... To the structure definition of omitempty keyword , To indicate that if this information is not provided , In sequence into json Don't include its default value when . Minor modifications , 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"`
}

Rerun , You can get the correct result .

trap

Bring convenience at the same time , Use omitempty There are also some small traps , One is that the keyword cannot ignore the nested structure . Or take the address type , This time we want to add a new... To the address structure field To express latitude and longitude , If there is a lack of relevant data , Ignore it for the moment . The new structure 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 in the original address data , Serialize the output after processing , We'll find that even with omitempty keyword , Output json I still brought 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 , You can define coordinates as pointer types , such Golang You can know the of a pointer “ Null value ” How much is it , Otherwise, we face a custom structure , Golang We can't guess the null value we want . So we have the following structure definition

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"
}

the other one “ trap ” yes , For using omitempty Defined field , If the value assigned to it is exactly equal to the default null value , In turn json This will not be output later field . For example, the longitude and latitude coordinate structure defined above , If we take latitude and longitude two field All plus omitempty

type coordinate struct {
    
	Lat float64 `json:"latitude,omitempty"`
	Lng float64 `json:"longitude,omitempty"`
}

And then we're talking about the Gulf of Guinea in Africa “ Origin coordinates ” Very interested , So I wrote the following code

func main() {
    
	cData := `{ "latitude": 0.0, "longitude": 0.0 }`
	c := new(coordinate)
	json.Unmarshal([]byte(cData), &c)

        //  Concrete processing logic ...

	coordinateBytes, _ := json.MarshalIndent(c, "", " ")
	fmt.Printf("%s\n", string(coordinateBytes))
}

Finally we got a

{
    }

This coordinate disappeared ! But our assumption is , If a location has no longitude and latitude information , Then it hangs in the air , There's no problem with that , But for the “ Origin coordinates ”, When we know exactly its latitude and longitude ,(0.0, 0.0) Still ignored . The correct way to write it is to change the definition in the structure into a pointer

type coordinate struct {
    
	Lat *float64 `json:"latitude,omitempty"`
	Lng *float64 `json:"longitude,omitempty"`
}

In this way, the null value starts from float64 Of 0.0 Change to pointer type nil , We can see the correct latitude and longitude output .

{
    
    "latitude": 0,
    "longitude": 0
}

版权声明
本文为[Handsome that handsome]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204210557450687.html