1. Introduction to structure labels
In addition to name and type, a field of a structure can also have an optional tag: it is a string attached to a field, which can be a document or other important tag.
Tag is a meta-information string associated with members of the structure during the compilation stage, and is read through the reflection mechanism when running.
A structure tag consists of one or more key-value pairs. Keys and values are separated by colons, and values are enclosed in double quotes. Use a space to separate key-value pairs
`key1:"value1" key2:"value2" key3:"value3"...` // Key-value pairs are separated by spaces
Note: There cannot be spaces on the left and right colons, otherwise the output result may be incorrect. Therefore, when writing tags, you must strictly abide by the key-value pair rules. The parsing code of structure tags has poor fault tolerance. Once the format is written incorrectly, no errors will be prompted during compilation and runtime.
The key will specify the resolution method of reflection including: json (JSON tag), orm (Beego tag), gorm (GORM tag), bson (MongoDB tag), form (form tag), and binding (form verification tag).
These systems use tag setting fields to set special properties and possible behaviors that should have when processing. These information are static and do not need to instantiate the structure and can be obtained through reflection.
2. json tags
The process of converting the structure slice into JSON in Go language is called marshaling, and the marshaling is completed through functions.
() You can convert json strings into structures, and many third-party package methods will read the structure tags.
type User struct { Name string `json:"username"` // The encoded field is username Age int `json:"userage"` // The encoded field is called userage Sex string // The encoded field is called Sex Hobby string `json:"-"` // Fields are not serialized} func main() { u1 := User{"zhangsan", 20, "male", "eat"} jsondata1, err := (u1) if err != nil { ("Format error") } else { ("User structure to json: %s\n", jsondata) } //OutputUserStructural transformationjson:{"username":"zhangsan","userage":20,"Sex":"male"}
Tag Options |
Instructions for use |
- |
Fields are not serialized Example: json:"-" |
omitempy |
Type zero value or empty value, ignore this field during serialization Example: json: ",omitempy" If the field name is omitted, use the structure field name |
Type |
Respecify the field type Example: json:"age,string" |
3. Gorm tag
GORM tends to be conventions rather than configurations. By default, GORM uses ID as the primary key, serpentine plural of the structure name as the table name, serpentine of the field name as the column name, and serpentine of the field name as the column name, and uses CreatedAt and UpdatedAt fields to track the creation and update time.
GORM defines a structure by default, which includes field ID, CreatedAt, UpdatedAt, and DeletedAt. It can be nested into a self-built structure. The tag name is case-insensitive. It is recommended to use camelCase style. Multiple tag definitions are separated by semicolons (;):
// Definitiontype Model struct { ID uint `gorm:"primaryKey"` CreatedAt UpdatedAt DeletedAt `gorm:"index"` }
Example:
type AddUserAuth struct { UUID string `gorm:"column:user_uuid;comment:userUUID;type:varchar(100);"` // User UUID User string `gorm:"column:user_name;comment:user名称;type:varchar(50);"` // User login name Cluster string `gorm:"column:cluster_name;comment:Cluster name;type:varchar(50);"` // k8s cluster NameSpace string `gorm:"column:namespace;comment:Namespace;type:varchar(50);"` // Namespace ServiceName string ` gorm:"column:service_name;comment:Application name;type:varchar(50);"` // Application name ServiceType string `gorm:"column:service_type;comment:Application Type;type:varchar(50);"` // Application Type}
The generated table creation statement is as follows:
CREATE TABLE `add_user_auths` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, `deleted_at` datetime DEFAULT NULL, `user_uuid` varchar(100) DEFAULT NULL COMMENT 'User UUID', `user_name` varchar(50) DEFAULT NULL COMMENT 'User Name', `cluster_name` varchar(50) DEFAULT NULL COMMENT 'Cluster Name', `namespace` varchar(50) DEFAULT NULL COMMENT 'namespace', `service_name` varchar(50) DEFAULT NULL COMMENT 'Application Name', `service_type` varchar(50) DEFAULT NULL COMMENT 'Application Type', PRIMARY KEY (`id`), KEY `idx_add_user_auths_deleted_at` (`deleted_at`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4
When creating a table with GORM Migrator, no fields that are ignored are created.
If you want to save UNIX (milli/nano) seconds timestamps instead of time, simply modify \ to int .
Field tags:
When declaring a model, tags are optional, and GORM supports the following tags:
Tag name |
illustrate |
column |
Specify the db column name |
type |
For column data types, it is recommended to use common types with good compatibility. For example: all databases support bool, int, uint, float, string, time, bytes and can be used with other tags, such as: not null, size, autoIncrement... Specifying database data types like varbinary(8) is also supported. When using the specified database data type, it needs to be a complete database data type, such as: MEDIUMINT UNSIGNED not NULL AUTO_INCREMENT |
size |
Specify the column size, for example: size:256 |
primaryKey |
Specify column as primary key |
unique |
Specify the column to be unique |
default |
Specify the default value of the column |
precision |
Specify the column's accuracy |
scale |
Specify the column size |
not null |
Specify the column as NOT NULL |
autoIncrement |
Specify the column as automatic growth |
autoIncrementIncrement |
Automatic step size, controlling the interval between continuous recordings |
embedded |
Nested fields |
embeddedPrefix |
column name prefix for embedded fields |
autoCreateTime |
Track the current time when created. For the int field, it tracks the second-level timestamp. You can use nano/milli to track nanoseconds and milli timestamps, for example: autoCreateTime:nano |
autoUpdateTime |
Track the current time when creating/update. For the int field, it tracks the second-level timestamp. You can use nano/milli to track nanoseconds and milli timestamps, for example: autoUpdateTime:milli |
index |
Create an index based on the parameters, and create a composite index with the same name for multiple fields. View the index to get details |
uniqueIndex |
Same as index, but creates a unique index |
check |
Create a check constraint, such as check:age > 13, view constraints Get details |
<- |
Set permissions for field writing, <-:create is created only, <-:update is updated only, <-:false is not written permission, <-:create is not created and updated permissions |
-> |
Set permissions for reading fields, ->:false No read permissions |
- |
Ignore this field, - No read and write permissions |
comment |
Add comments to fields during migration |
Related tags:
GORM allows the configuration of foreign keys, constraints, and many2many tables for associations through tags:
Tag name |
illustrate |
foreignKey |
Specify the column of the current model as the foreign key to join the table |
references |
Specifies the column name of the reference table, which will be mapped as a join table foreign key |
polymorphic |
Specify polymorphic types, such as model name |
polymorphicValue |
Specify polymorphic values, default table names |
many2many |
Specify the join table name |
joinForeignKey |
Specifies the foreign key column name of the join table, which will be mapped to the current table |
joinReferences |
Specifies the foreign key column name of the join table, which will be mapped to the reference table |
constraint |
Relational constraints, such as: OnUpdate, OnDelete |
4. Form tags
Gin provides model binding, which binds form data and model to facilitate parameter checksum use.
Model binding:
// Form datatype LoginForm struct { UserName string `form:"username"` Password string `form:"password"` Email string `form:"email"` } // Model or service layer Modeltype Email struct { Email string Password string } func EmailLogin (c *) { var email LoginForm if err := (&email); err != nil { ... } // Get form data bureau args := Email { Email: , Password: , } // Subsequent use of parameters ... }
Bind form email data through form:"email". Then get the parameter value through Bind(), ShouldBind() and other methods.
5. Binding tags
Gin mainly provides two sets of binding methods, Must bind and Should bind. gin/binding Built-in model binding implementation, extracting requested data to the appropriate binder.
Must bind: If the verification fails, a specific error page will be terminated or thrown.
Should bind: There is a binding error, and this error will be returned and the corresponding request and error need to be handled by yourself.
The Gin framework itself has implemented multiple bindings, which are usually used to bind requested data, with different structural instances corresponding to it. The bindings implemented are JSON, XML, Form, Query, FormPost, FormMultipart, ProtoBuf, MsgPack, YAML, Uri.
Gin uses the validator.v10 package for data verification, which provides a variety of data verification methods, and uses the binding:" tag to perform data verification.
See github for verification rules:validator
Example:
type LoginForm struct { Email string `form:"email" binding:"email"` UserName string `form:"username" binding:"username"` Password string `form:"password" binging:"required,min=6,max=10"` }
Special symbols:
symbol |
illustrate |
, |
Separate multiple label options, no spaces between commas |
- |
This field is not validated |
| |
Use multiple options to satisfy one of them |
Must be verified
Tag Options |
illustrate |
Example |
required |
It means that the field value must be entered and cannot be the default value. |
binding:required |
omitempty |
If the field is not set, it is ignored |
binding:reqomitemptyuired |
String verification
Tag Options |
Instructions for use |
Example |
contains |
Parameter values contain settings substring |
binding: whether "contains=ares" contains the ares string |
excludes |
Parameter values do not contain settings substrings |
binding: "excludes=ares" does not contain the ares string |
startswith |
String prefix |
Does binding: "startswith=ares" start with tom |
endswith |
String prefix |
Does binding: "endswith=ares" end in tom |
Range verification
Range verification: slices, arrays, maps, and strings, verify their length; values, verify the size range.
Tag Options |
Instructions for use |
Example |
len |
The parameter value is equal to the given value |
binding:"len=3" equals 3 |
ne |
Not equal to |
binding:"ne=3" does not equal 3 |
max |
Maximum value, less than or equal to parameter value |
binding:"max=3" is less than or equal to 3 |
min |
Minimum value, greater than or equal to parameter value |
binding:"min=3" is greater than or equal to 3 |
lte |
The parameter value is less than or equal to the given value |
binding:"lte=3" is less than or equal to 3 |
gte |
The parameter value is greater than or equal to the given value |
binding:"gte=3" is greater than or equal to 3 |
lt |
The parameter value is less than the given value |
binding:"lt=3" is less than 3 |
gt |
The parameter value is greater than the given value |
binding:"gt=3" is greater than 3 |
oneof |
The parameter value can only be one of the enumeration values. The value must be a numeric value or a string, separated by spaces. If there are spaces in the string, the string is surrounded by single quotes. |
binding:"oneof=red green" |
Field verification
Tag Options |
Instructions for use |
eqcsfield |
fields are equal across different structures, such as struct1 field1 is equal to struct2 field2 |
necsfield |
Not equal across different structure fields |
eqfield |
Verify equality of the same structure field, for example: enter the password twice |
nefield |
Verification of fields not equal to the same structure |
gtefield |
greater than or equal to the same structure field |
ltefield |
Less than or equal to the same structure field |
Example:
// Verification of different structurestype S1 struct { F1 string `validate:eqcsfield=S2.F2` S2 struct { F2 string } } // The same structure field is the same verificationtype Email struct { Email string `validate:"lte=4"` Pwd string `validate:"min=10"` Pwd2 string `validate:"eqfield=Pwd"` } // The same structure field is not equaltype User struct { Name string `validate:"lte=4"` Age int `validate:"min=20"` Password string `validate:"min=10,nefield=Name"` }
Other verifications
Tag Options |
Instructions for use |
Example |
ip |
Legal IP address verification |
binding:"ip" |
Legal email verification |
binding:"email" |
|
url |
Legal URL |
binding:"url" |
uri |
Legal URI |
binding:"uri" |
uuid |
UUID Verification |
binding:"uuid" |
datetime |
Legal time format value verification |
binding:"datetime=2006-01-02" |
json |
JSON data verification |
validate:"json" |
numeric |
Numerical verification Regularity: ^[-+]?[0-9]+(?:\\.[0-9]+)?$ |
validate:"numeric" |
number |
Integer Verification Regular: ^[0-9]+$ |
validate:"number" |
alpha |
Alphabetical string verification Regular: ^[a-zA-Z]+$ |
validate:"alpha" |
alphanum |
Alphanumeric string verification Regular: ^[a-zA-Z0-9]+$ |
validate:"alphanum" |
ascii |
Ascii Character Verification |
validate:"ascii" |
6. Ini tags
ini is a commonly used configuration file format on Windows, and go-ini is a third-party library used to operate ini files in the Go language.
If you use the ini format configuration, you need to map the configuration file fields to the structure variable. If the key name is different from the field name, you need to specify the corresponding key name in the structure label. The standard library encoding/json and encoding/xml can directly correspond to the key name to the field name, while the go-ini library cannot, so the corresponding key name needs to be specified in the structure label.
## Configuration Fileuser_name = ares age = 20 // Configuration file map structuretype Config struct { UserName string `ini:"user_name"` // Ini tag specifies the lower key name Age string `ini:"age"` }
Summarize
This is all about this article about the struct tag in go language. For more related go struct tag content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!