Custom type
There are some basic data types in Go language, such as string, integer, floating point, Boolean and so on. In Go language, you can use the type keyword to define a custom type.
A custom type defines a completely new type. We can define it based on built-in basic types or through struct. For example:
MyInt is a new Type defined by the type keyword and has the characteristics of Int.
Type alias
Type alias is a new feature added in version Go 1.9.
Typealis stipulates that Typealis only an alias of Type, and in essence Typealis and Type are the same type. Just like a child who has a nickname and a baby's name when he is a child and uses a scientific name after school, the English teacher will give him an English name, but these names all refer to him.
Type Type Alias = Type
Rune and byte we saw before are both type aliases, and their definitions are as follows:
The difference between type definition and type alias
On the surface, there is only an equal sign between a type alias and a type definition. We can understand the difference between them through the following code.
The results show that type A is the main type. NewInt, which means the type of NewInt defined under the main package. The type of b is int. MyInt type will only exist in the code, and there will be no MyInt type after compilation.
The basic data types in Go language can express the basic attributes of some things, but when we want to express all or part of the attributes of a thing, it is obviously impossible to meet the demand by using a single basic data type. Go language provides a user-defined data type, which can encapsulate many basic data types. This data type is called structure and its English name is struct. In other words, we can define our own types through struct.
Go language realizes object-oriented through struct.
Definition of structure
Use the type and struct keywords to define the structure. The specific code format is as follows:
These include:
For example, we define a personnel structure with the following code:
Fields of the same type can also be written in one line,
In this way, we have a user-defined person with three fields: name, city and age, which represent name, city and age respectively. In this way, we can use this person structure to express and store people's information in the program conveniently.
The basic data type built into the language is used to describe a value, while the structure is used to describe a set of values. For example, a person has a name, age and city of residence, which is essentially an aggregated data type.
Structural instantiation
Only when the structure is instantiated will the memory be truly allocated. That is, the fields of the structure must be instantiated before they can be used.
Basic instantiation
For example:
We access the fields (member variables) of the structure. , such as p 1.name, p 1.age, etc.
Anonymous structure
Anonymous structures can also be used in some scenarios, such as defining some temporary data structures.
Create pointer type structure
We can also instantiate the structure with the new keyword and get the address of the structure. The format is as follows:
From the printed results, we can see that p2 is a structural pointer.
It should be noted that the Go language supports direct use. Access the members of the structure.
Address of the instantiated structure
Use&; The address operation is equivalent to a new instantiation operation of the structure type.
P3.name = "seven meters" is actually (* P3) at the bottom. Name = "seven meters", which is the grammar sugar that Go language helps us realize.
Structure initialization
For uninitialized structures, their member variables are all zero values corresponding to their types.
Initialize with a key-value pair
When a structure is initialized with a key-value pair, the key corresponds to the field of the structure and the value corresponds to the initial value of the field.
You can also initialize key-value pairs of structure pointers, for example:
When some fields have no initial values, these fields may not be written. At this time, the value of the field without specifying the initial value is zero of the field type.
Initialize with a list of values
You can abbreviate when initializing the structure, that is, you can write the value directly without writing the key when initializing:
When initializing with this format, you need to pay attention to:
Structural memory layout
Structure occupies a contiguous block of memory.
Output:
Advanced knowledge points about Go memory alignment Recommended reading: Go memory alignment is just right.
Interview question
What is the execution result of the following code?
constructors
The structure of Go language has no constructor, so we can implement it ourselves. For example, the following code implements the constructor of person. Because struct is a value type, if the structure is complex, the performance overhead of value copying will be great, so the constructor returns the pointer type of the structure.
Call constructor
Method and receiver
A method in Go language is a function that acts on a specific type of variable. This special type of variable is called a receiver. The concept of receiver is similar to this or self in other languages.
The definition format of this method is as follows:
Among them,
For example:
The difference between a method and a function is that a function does not belong to any type, and a method belongs to a specific type.
Recipient of pointer type
The receiver of pointer type consists of pointers of structure. Due to the characteristics of pointers, any member variable of the receiver pointer is modified when the method is called, and the modification will be effective after the method ends. This method is very close to this or self in object-oriented language. For example, we add a SetAge method to Person to modify the age of the instance variable.
Call this method:
Receiver of value type
When a method acts on a value type receiver, the Go language will copy the receiver's value when the code runs. You can get the member value of the receiver in the method of the value type receiver, but the modification operation is only for the copy, and the receiver variable itself cannot be modified.
When should I use a pointer receiver?
Any type of addition method
In Go language, the type of the receiver can be any type, not just the structure, and any type can have a method. For example, we can use the type keyword to define a new custom type based on the built-in int type, and then add methods for our custom type.
Note: Non-local types cannot define methods, which means that we cannot define methods for other package types.
Anonymous field of structure
Anonymous fields use the type name as the field name by default, and the structure requires that the field name must be unique, so there can only be one anonymous field of the same type in a structure.
Nested structure
A structure can be nested with another structure or a pointer to a structure.
Nested anonymous structure
When accessing a structure member, the field is searched in the structure first, and if it cannot be found, it is searched in an anonymous structure.
Field names of nested structures conflict.
The same field name may exist in the nested structure. At this point, in order to avoid ambiguity, it is necessary to specify the field of specific embedded structure.
"Inheritance" of Structure
Using structure in Go language can also realize object-oriented inheritance in other programming languages.
Visibility of structure fields
Capitalized fields in the structure indicate public access, and lowercase fields indicate private access (only in the package that defines the current structure).
Structure and JSON serialization
JSON(JavaScript Object Notation) is a lightweight data exchange format. It is convenient for people to read and write. And is convenient for machine analysis and generation. JSON key-value pairs are a way to save JS objects. Key names in key/value pairs are written in front, enclosed in double quotation marks "",separated by colons:, followed by values; Use English to separate multiple key values.
Structural marker
Tags are meta-information of structures, which can be read by reflection mechanism at runtime. The tag is defined after the structure field and enclosed in a pair of back quotes. The specific format is as follows:
` key 1:" value 1 " key 2:" value 2 " '
A structural label consists of one or more key-value pairs. Keys and values are separated by colons, and values are enclosed in double quotes. Key value pairs are separated by spaces. Note: When writing tags for structures, the rules of key-value pairs must be strictly observed. The parsing code of structural tags has poor fault tolerance. Once the format is wrong, the compiler and runtime will not prompt the error, and the value cannot be obtained correctly through reflection. For example, do not add spaces between keys and values.
For example, we define the tags used in json serialization for each field of the Student structure: