Note: This article mainly introduces how to define and use custom types in the Go language, involving certain programming basics and syntax. If you have any unfamiliar things, it is recommended to learn the relevant basic knowledge first. You can read another article from me:Unlock Golang data types: Learn to use multiple types to improve code readability and maintainability
1. What is a custom type
In Go language, a custom type refers to a new type defined using the type keyword. It can be an alias for the basic type, or a new type composed of structures, functions, etc. Custom types can help us better abstract and encapsulate data, making the code easier to read, understand and maintain.
For example, we can define a custom type to represent concepts in a certain field, such as time, date, currency, etc. These concepts have different implementation methods and representation methods in different application scenarios. Using custom types can make the code more readable and facilitate subsequent expansion and maintenance.
2. How to define custom types
In Go, you can define a new type using the type keyword, and the syntax is as follows:
type NewType OldType
Among them, NewType is the name of the new type, and OldType can be an alias for any basic type or an existing type. In this way, a new type can be created so that this new type has different characteristics from the original type.
For example, we can use the type keyword to define a new type to represent concepts in a certain field, such as date:
type Date string
In this example, we use the type keyword to define a new type Date, which is an alias for the string type. This new type can be used to represent dates, for example:
var today Date = "2023-04-29"
Here is a variable today, whose type is Date, which is the date type we just defined. It should be noted that although Date is an alias for string, it is a different type from the string type and cannot be assigned or compared to each other.
In addition, we can also use the type keyword to define a structure type:
type Person struct { Name string Age int }
In this example, we define a Person structure type that contains two fields Name and Age. This structure type can be used to represent a person's basic information. We can use this type to create a Person variable:
var p Person = "Tom" = 18
It should be noted that in Go language, custom types are strongly typed, that is, you cannot assign the value of one type to a variable of another type at will, and type conversion is required to be assigned. For example, we cannot assign a variable of type int to a variable of type string, and we need to use functions in the strconv package for type conversion.
3. Methods for custom types
In addition to defining a new type, we can also define methods for custom types, which are functions associated with the type, and can be called on instances of that type. The method makes the type have richer behavior and can operate and process the data of the type.
In Go language, use the func keyword to define the method, and the syntax is as follows:
func (receiver Type) methodName(parameters) returnType { // Method body }
Where, receiver represents the receiver of the method, which can be a value or pointer of the type, Type represents the type to which the method belongs, methodName represents the name of the method, parameters represent the parameter of the method, and returnType represents the return value type of the method.
For example, we can define a method for the Person structure type defined above to calculate the age of the person:
func (p Person) GetAge() int { return }
In this example, we define a GetAge method whose receiver is a Person type value that returns the person's age. We can call this method in the following ways:
var p Person = 18 age := ()
Here, a Person variable p is created, and its age is set to 18. Then, the GetAge method of p is called, returning its age, and assigning it to the age variable.
It should be noted that methods in Go can be defined on any type, not just struct type, for example, methods can be defined on int type, methods can be defined on aliases of custom types, etc.
4. Embedding and Combination of Custom Types
Embedding and composition of custom types is a very important concept in the Go language and can help us better organize and reuse code. Embedding and composition are essentially a way of code reuse, where one type's properties can be reused into another type.
In Go, using structures can implement embedding and combination of types. Embedding means embedding one type as a field of the structure into another type, so that the type can use the characteristics of the embedded type. Combination means combining multiple types together to form a new type so that the type can have the characteristics of multiple types simultaneously.
For example, we can define a new type Employee, which combines two types of features: Person and Company:
type Person struct { Name string Age int } type Company struct { Name string Address string } type Employee struct { Person Company Salary float64 }
In this example, we define two structure types, Person and Company, and then define a new Employee type, which contains the characteristics of two types, Person and Company, as well as our own salary attributes. In this way, we can reuse the features of Person and Company types in the Employee type and add new properties and methods based on them.
When using embedding and combination, we can initialize a structure variable through structure literals, such as:
var e Employee = Employee{ Person{Name: "Tom", Age: 30}, Company{Name: "Google", Address: "Mountain View"}, 100000.0, }
In this example, we use the structure literal to initialize a variable e of type Employee, where both Person and Company fields are initialized using literals.
The properties and methods of e can be accessed in the following ways:
() // Output "Tom" () // Output 30 () // Output "Mountain View" () // Output 100000.0 (()) // Output 30
Here we use e to access the properties and methods of the Person and Company types embedded in it, as well as our own salary attributes. It should be noted that if there are fields or methods of the same name in the embedded type, you can access the fields or methods of the specified type by adding the field name or method name.
5. Custom type value receiver and pointer receiver
When defining a method of type, a value receiver or a pointer receiver can be used, and the difference is that the type of the method receiver is a value of that type or a pointer.
The value recipient indicates that the receiver of the method is a value of this type, and modifying the value in the method will not affect the original value. The pointer receiver indicates that the receiver of the method is a pointer of this type, and modifying the value pointed to by the pointer in the method will affect the original value.
For example, we can define a method to modify age for the Person type defined above:
func (p Person) SetAge(age int) { = age }
In this example, we define a SetAge method whose receiver is a Person-type value that is used to modify the person's age. However, since the method recipient is a value of this type, modifying it in the method will not affect the original value, so the method cannot implement the function of modifying age.
To solve this problem, we can use pointer receivers to define the method:
func (p *Person) SetAge(age int) { = age }
In this example, we use the pointer receiver to define the SetAge method, which is a pointer of type Person. By using pointer receivers, we can modify the value pointed to by the pointer in the method, thereby achieving the function of modifying age.
It should be noted that when the value of the type is large, the use of pointer receivers is more efficient than the value receivers, because the pointer receivers pass a pointer to the value, while the value receivers pass a copy of the value. If the value is large, the overhead of copying will be greater.
6. Custom type method
In addition to defining instance methods, we can also define type methods. A type method is a method that belongs to a type, not an instance method. In a type method, the type name can be used as the receiver, not the variable name of the instance.
For example, we can define a type method for the Person type to create a variable of the new Person type:
func NewPerson(name string, age int) *Person { return &Person{name, age} }
In this example, we define a NewPerson method whose receiver is a pointer of type Person to create a new Person variable. In the method, we use the type name Person to create a new variable of type Person and return a pointer to that variable.
The NewPerson method can be called in the following ways:
p := NewPerson("Tom", 30) (p) // Output "&{Tom 30}"
In this example, we call the NewPerson method, create a new variable p of Person type, and output a pointer to that variable.
It should be noted that the difference between a type method and an instance method is that the receiver has different types. The receiver of a type method is a pointer to the type itself, while the receiver of the instance method is a pointer or value of an instance of that type.
7. Summary
In Go, custom types are very common operations, and by custom types, we can better organize and manage code. In this article, we introduce the basic concepts and syntax of custom types in Go, including type alias, structures, embeddings and combinations, value receivers and pointer receivers, type methods, etc.
I hope that through the introduction of this article, you can help you understand and master the relevant knowledge of custom types in Go more deeply, and be flexibly applied in actual development.
This is the article about custom types in Go language that you know about this article. For more relevant Go custom types, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!