1. The concept and definition of Golang structure
A structure is a composite type in Golang, which is a data structure composed of a set of data fields of the same or different types. A structure is a user-defined type that can be used to encapsulate multiple fields to enable the combination and abstraction of data. In Golang, structures are a very flexible and highly extensible type, which supports advanced features such as nesting, composing, and methods.
The syntax for defining a structure is as follows:
type StructName struct { Field1 Type1 Field2 Type2 // ... }
Among them, StructName is the name of the structure, Field1, Field2, etc. are the field names of the structure, and Type1, Type2, etc. are the field types of the structure. Multiple fields can be defined, separated by spaces between field names and field types.
Here is an example defining a Person structure:
type Person struct { Name string Age int }
In the above code, we define a structure called Person, which contains two fields: Name and Age. Where Name is the string type and Age is an integer.
2. Instantiation of Golang structure
In Golang, there are many ways to instantiate structures, including using structure literals, new functions, var keywords, and constructors.
Structural literal
Structural literals are an easy way to create instances of structures. When using structure literals, we need to specify the field name and field value of the structure, separate multiple fields with commas, and the entire structure is enclosed in curly braces.
Here is an example of creating a Person structure using structure literals:
p := Person{Name: "Tom", Age: 25}
In the above code, we create a Person structure called p and initialize it to {Name: "Tom", Age: 25}. Where, the value of the Name field is "Tom" and the value of the Age field is 25.
2.1 new function
The new function is a built-in function in Golang that creates a pointer to a newly allocated zero value of type T. When using the new function, we need to pass a type parameter that represents the type to allocate memory.
Here is an example of using the new function to create a Person structure:
p := new(Person)
In the above code, we create a Person structure pointer named p. Since structures created with the new function are initialized to zero values, all field values of p are default values.
2.2 var keywords
The var keyword can also be used to create instances of structures. When using the var keyword, we need to specify the variable name and type, and then initialize it with the equal sign to the structure literal.
Here is an example of creating a Person structure using the var keyword:
var p Person = Person{Name: "Tom", Age: 25}
In the above code, we create a Person structure called p and initialize it to {Name: "Tom", Age: 25}. Since the var keyword is used, you can prefix the variable name with a type.
2.3 Constructor
A constructor is a special function that is used to create and initialize instances of a structure. In Golang, the constructor usually starts with New and returns a pointer to the structure.
Here is an example of using constructors to create a Person structure:
func NewPerson(name string, age int) *Person { return &Person{Name: name, Age: age} } p := NewPerson("Tom", 25)
In the above code, we define a constructor named NewPerson, which takes two parameters: name and age, and returns a pointer to the Person structure. By calling the NewPerson function, we create a Person structure named p and initialize it to {Name: "Tom", Age: 25}.
3. Inlay and combination of Golang structures
In Golang, the inlay and combination of structures are an important means to implement code reuse and inheritance. The inlay of a structure can allow one structure type to contain all fields and methods of another structure type, thereby enabling code reuse. The combination of structures is to combine one or more structure types to form a new structure type, thereby achieving inheritance and polymorphism.
3.1 Inlay of structure
The inlay of a structure is to nest one structure type in another structure type. The fields and methods defined in the embedded structure will be inherited into the outer structure, thereby realizing code reuse.
Here is an example of using structure embedding:
type Address struct { City string State string } type Person struct { Name string Age int Address // Embed Address structure } func main() { p := Person{ Name: "Tom", Age: 25, Address: Address{ City: "Beijing", State: "China", }, } () // Tom () // 25 () // Beijing () // China }
In the above code, we define two structure types: Address and Person. Among them, the Address structure contains two fields: City and State; the Person structure embeds the Address structure and adds two new fields: Name and Age.
By embedding the Address structure, the Person structure inherits all fields of the Address structure. Therefore, we can access the Address field in the Person structure through and .
3.2 Combination of structures
A combination of structures is to combine one or more structure types together to form a new structure type. In a combined structure, fields and methods in the combined structure can be overloaded or extended to achieve inheritance and polymorphism.
Here is an example of using structure combinations:
type Animal struct { Name string } func (a *Animal) Say() { ("%s says: ...\n", ) } type Dog struct { *Animal // Combining Animal structure } func (d *Dog) Say() { ("%s says: Woof woof!\n", ) } func main() { a := &Animal{Name: "Unknown"} d := &Dog{Animal: a} () // Unknown says: ... () // Unknown says: Woof woof! }
In the above code, we define two structure types: Animal and Dog. Animal structure contains a field Name and a method Say; the Dog structure combines the Animal structure and overloads the Say method.
By combining Animal structures, the Dog structure inherits all fields and methods in the Animal structure. When overloading the Say method, we use the value of the Name field, which means that the Dog structure inherits the Name field in the Animal structure.
3.3 Anonymous fields and method sets of structures
In Golang, structure fields can be anonymous, meaning that their types can be embedded directly into the structure without specifying the field name. The value of an anonymous field can be accessed directly, just like other fields in a structure.
3.3.1 Anonymous field
Anonymous fields are similar to inline structures, but they do not inherit field names and methods. Instead, the type of an anonymous field is treated as a field name, and the value of the field can be accessed by the type name.
Here is an example of using an anonymous field:
type Person struct { Name string int // Anonymous field } func main() { p := Person{Name: "Tom", int: 25} () // Tom () // 25 }
In the above code, we define a Person structure type that contains a Name field and an anonymous int type field. Through anonymous fields, we can directly access the int type field in the Person structure without using the field name.
3.3.2 Method Set
In Golang, each struct type has a method set, which is a collection of all methods on that struct type. A method set can be divided into two parts: a value method set and a pointer method set.
The value method set contains methods whose recipients are of value type, while the pointer method set contains methods whose recipients are of pointer type. When we call a method on the struct type, Golang automatically determines the recipient value to be passed to the method based on the receiver type in the method set.
In the following example, we define a Person structure type, and define a value method and a pointer method on it:
type Person struct { Name string Age int } func (p Person) GetName() string { return } func (p *Person) SetAge(age int) { = age } func main() { p1 := Person{Name: "Tom", Age: 25} (()) // Tom (30) () // 30 p2 := &Person{Name: "Jack", Age: 35} (()) // Jack (40) () // 40 }
In the above code, we define a Person structure type and define a value method GetName and a pointer method SetAge on it. When calling a method, Golang automatically determines the recipient value to be passed to the method based on the receiver type in the method set.
When calling a method, Golang passes p1 as the receiver value of the method to the GetName method. Since the receiver type of the GetName method is of value type, Golang will copy p1 and pass the copied value to the GetName method.
When calling a method, Golang passes &p1 as the receiver value of the method to the SetAge method. Since the receiver type of the SetAge method is a pointer type, Golang passes &p1 as a pointer to p1 to the SetAge method. In the SetAge method, we can modify the Age field in the p1 structure through pointers.
When calling methods and methods, Golang automatically passes &p2 as the receiver value of the method to the method, because p2 is a pointer to the Person structure.
4. Definition and use of Golang method
In Go, a method is a special function that is associated with a type that can operate on instances of that type. In Go language, the way methods are defined is very similar to the way functions are defined, the only difference is that the method needs to be preceded by its name. Here is an example:
type Person struct { name string age int } func (p Person) sayHello() { ("Hello, my name is %s\n", ) }
In this example, we define a method called "sayHello" that is associated with the Person type. The recipient of this method is "p Person", indicating that the method acts on an instance of type Person. In the method body, we use the attribute "name" of the receiver "p" to output a greeting.
5. Recipient of Golang method
In Go, the receiver of a method can be a pointer type or a value type. If you use the pointer type as the receiver, you can modify the attribute value of the structure in the method. Here is an example:
type Person struct { name string age int } func (p *Person) setAge(newAge int) { = newAge } func main() { p := Person{"Tom", 20} (30) ("%s's age is %d\n", , ) }
In this example, we define a method called "setAge" with the receiver of "p *Person", indicating that it receives a pointer to type Person. In the method body, we use the attribute "age" of the pointer "p" to modify the age attribute of the Person structure. In the main function, we use this method to modify the age of the Person instance and output the modified result.
6. Golang pointer type method
In Go language, a pointer type method can be called by an instance of a value type and an instance of a pointer type. This is because when called, instances of value type are automatically converted to instances of pointer type. Here is an example:
type Person struct { name string age int } func (p *Person) sayHello() { ("Hello, my name is %s\n", ) } func main() { p := Person{"Tom", 20} () (&p).sayHello() }
In this example, we define a method called "sayHello" with the receiver of "p *Person", indicating that it receives a pointer to type Person. In the main function, we define a Person instance "p", and then use an instance of the value type and an instance of the pointer type to call the "sayHello" method.
7. Golang method and interface
In Go language, methods are one of the conditions for implementing interfaces. A type can only be called an implementation class of the interface type if it implements all methods defined by the interface. Here is an example:
type Animal interface { Speak() string } type Dog struct{} func (d Dog) Speak() string { return "Woof!" } type Cat struct{} func (c Cat) Speak() string { return "Meow!" } func main() { animals := []Animal{Dog{}, Cat{}} for _, animal := range animals { (()) } }
In this example, we define an interface called "Animal" which contains a method called "Speak". We then define two types: "Dog" and "Cat", both implementing the "Speak" method defined in the "Animal" interface. In the main function, we define an Animal-type slice "animals", add "Dog" and "Cat" instances to the slice, and iterate over the slice, outputting the return value of the "Speak" method of each instance.
8. Combination of Golang structure and interface
In the above sections, we have introduced the definition and use of Golang structures and methods, as well as the design and implementation of interfaces. In this section, we will explore the combination of Golang structures and interfaces, that is, how to use structures and interfaces to achieve a more flexible and scalable design.
In Golang, we can use a combination of structures and interfaces to achieve polymorphism. Polymorphism is a concept in object-oriented programming that allows different objects to use the same interface to achieve different behaviors. Through polymorphism, we can make different objects have different behaviors, thus achieving a more flexible and scalable design.
First, let's look at a simple example of how to use a combination of structures and interfaces to achieve polymorphism. Suppose we have a shape interface and two shape structures representing rectangles and circles, respectively. We can define the shape interface as follows:
type Shape interface { Area() float64 }
Then, we can define rectangular and circular structures to implement the methods in the shape interface:
type Rectangle struct { Width float64 Height float64 } func (r Rectangle) Area() float64 { return * } type Circle struct { Radius float64 } func (c Circle) Area() float64 { return * * }
Now we can define a common function, using the shape interface as a parameter to calculate the area of different shapes:
func CalculateArea(shape Shape) float64 { return () }
Finally, we can use this function to calculate the area of different shapes:
rect := Rectangle{Width: 3, Height: 4} circle := Circle{Radius: 5} (CalculateArea(rect)) // Output 12 (CalculateArea(circle)) // Output 78.53981633974483
rect := Rectangle{Width: 3, Height: 4} circle := Circle{Radius: 5} (CalculateArea(rect)) // Output 12 (CalculateArea(circle)) // Output 78.53981633974483
rect := Rectangle{Width: 3, Height: 4} circle := Circle{Radius: 5} (CalculateArea(rect)) // Output 12 (CalculateArea(circle)) // Output 78.53981633974483
Through the above example, we can see that using a combination of structures and interfaces, polymorphism can be achieved, so that different objects have different behaviors. In actual development, we can use this approach to achieve a more flexible and scalable design.
In addition to the above examples, we can also use a combination of structures and interfaces to achieve more complex designs. For example, we can define a car interface and two car structures, representing sedans and off-road vehicles, respectively. Then, we can define a common function that uses the car interface as a parameter to calculate the fuel consumption of different cars. Through this approach, we can implement a general-purpose automotive fuel consumption calculator, which allows us to design and develop more flexibly.
In short, using a combination of structures and interfaces allows us to achieve a more flexible and scalable design. Through polymorphism, we can allow different objects to use the same interface to achieve different behaviors, making our code clearer and easier to maintain. In actual development, we can use a combination of structures and interfaces to implement various complex designs, making our code more elegant and efficient.
9. Golang Structure Tags
In Golang, we can add labels on the fields of the structure so that the metadata of this field can be obtained by reflection at runtime. A structure tag is a kind of metadata that can be added to a structure field. It can be used to describe the properties, formats, etc. of this field.
The basic syntax of structure tags is as follows:
type MyStruct struct { FieldName FieldType `tag:"tagValue"` }
Among them, FieldName is a field in the structure, FieldType is the type of this field, and tagValue is the tag value of this field.
For example, we can add a json tag to the Name field of the Person structure to specify the name that this field should use when encoding the structure into JSON format, the code looks like this:
type Person struct { Name string `json:"name"` Age int `json:"age"` }
The Name field of this structure is marked json:"name", indicating that when encoding this structure into JSON format, this field should use name as the field name.
We can use Golang's built-in reflection mechanism to get the label value of this structure field. For example, we can use the Type and FieldByName methods in the reflect package to get the label value of the Name field of the Person structure. The code is as follows:
p := Person{Name: "Tom", Age: 18} t := (p) f, _ := ("Name") (("json")) // Output: name
This code creates an instance of the Person structure named p and uses the reflection mechanism to obtain the json tag value of the Name field of the structure.
10. Summary
This article introduces the relevant knowledge of structures and methods in the Golang language. We start from the definition and initialization of structures, and deeply explore the concepts of structure members and anonymous fields, method sets, and nesting and combinations of structures. By studying this article, you should be able to be proficient in using structures and methods to implement various functions in object-oriented programming. At the same time, you should also be able to clearly understand the internal implementation principles of structures and methods in the Golang language, so as to better utilize them to solve practical problems.
If you have any questions or suggestions about the content introduced in this article, please leave a message in the comment area and we will reply as soon as possible.
The above is a detailed content of Golang structures and methods in one article. For more information about Golang structures and methods, please pay attention to my other related articles!