A Go tag is a string in a structure, a bit like an annotation in PHP. It has strict formatting requirements and is usually used to reflect methods in a package to access it. The tag is used to declare the attributes of a field in the structure. Let’s take a look at the use of structure tags in JSON conversion:

package main

import (
	"encoding/json"
	"fmt"
)

type User struct {
	Name   string `json:"username"`
	Age    int    `json:"userage"`
	Salary int    `json:"usersalary"`
}

func main(a) {
	myself := User{"Earthy excavator".18.2000}
	jsondata, err := json.Marshal(myself)
	iferr ! =nil {
		fmt.Println("Formatting error")}else {
		fmt.Printf("User struct to json: %s\n", jsondata)
	}
}

Copy the code

The output is:

User struct to json: {"username":"Earthy excavator"."userage":18."usersalary":2000}
Copy the code

The json.marshal () method of the “encoding/json” package converts the encoding to JSON. It reads the tag in the User structure. The key of the JSON key-value pair is the tag name. Json.unmarshal () converts json strings into structures, which are read by many third-party package methods. Note that the outer symbol in the label is the key above the keyboard Tab key, not the single quotation mark.

It can be seen in the Gin documentation:In the example aboveform:"user" The name of the parameter is user,binding:"required"Indicates that this parameter is required.

It can be seen that the structure tag of Go language can use multiple tags in one field, and the structure tag needs to be read by reflection mechanism.

Go language reflex

Reflect.valueof () and reflect.typeof () are two methods of the realect package that get the type and ValueOf a variable, as shown in the code below

package main

import (
	"fmt"
	"reflect"
)

type User struct {
	Name string `data:"test" test:"haha"`
	Age  string `json:"test"`
}

func main(a) {
	user := User{"Earthy" "."Test"}
	user_value := reflect.ValueOf(user) // Get the value of the variable

	user_type := reflect.TypeOf(user) // Get the type
	fmt.Println(user_value, user_type)

	// Get the value of the structure tag
	name_data := user_type.Field(0)            //user first field
	name_tag_data := name_data.Tag.Get("data") // Get the value of data in the Tag of the first field of the structure
	fmt.Println("name_data:", name_tag_data)
}
Copy the code

reflection

The above code realizes the reflection of the Go language to obtain the value of the structure tag. Through this example, it is not thought of the ORM model method and data table structure migration implemented in the previous article. Let’s expand on reflection a little bit. Reflection is essentially trying to get the type information and memory structure of an object as the code is running. In Go we usually define variables with a static type, such as int, String,floast, but that’s not the underlying data type. The underlying type of string is a struct, and the data type of Go language is divided into static type and low-level type, for example:

type MyInt int

var i int
var j MyInt
Copy the code

Both I and j have an underlying type of int. I has a static type of int and j has a static type of MyInt, so they can’t be equal. They have different static types. So a Go variable has a value and it has a static type or concrete type, which is also called a concrete type, and the static type is determined at compile time. The implementation of reflection is that the variable will store its type information to the interface when assigning a value and the corresponding type. Type and value are converted by the interface. The above code uses the structure of User to implement this conversion interface.