Structure of learning notes of Go programming language
I environment
Centos8.5, go1.17.5 linux/amd64
II concept
A structure is an aggregate data type that combines zero or more named variables of any type. Each variable is called a member of a structure.
III Declaration / initialization
1) Define a structure type Human, and then define a named structure variable child through it.
8 type Human struct { 9 Name string 10 Age int 11 Height float64 12 } 13 14 var child Human 15 16 func main() { 17 child.Name = "Jim" 18 child.Height = 90.0 19 child.Age = 4 20 21 fmt.Printf("%#v\n", child) 22 }
The operation results are as follows
The member variables of a structure are usually written on one line, and the name of the variable is in front of the type, but continuous member variables of the same type can be written on the same line.
The order of member variables is very important for structure identity. If we adjust the order of members, we are defining a different structure type.
If the member variable name of a structure is capitalized, the variable is exportable, which is the main access control mechanism of Go. A structure can contain both exportable and non exportable member variables.
In the named structure type {S, a member variable with the same structure type} S cannot be defined, that is, an aggregate type cannot contain itself. Otherwise, the compiler will report an error and prompt "invalid recursive type", as shown below
However, in the structure type * S , you can define a pointer type of * S , that is, * S, so that you can create some recursive data structures, such as linked lists and trees.
2) Zero value
The zero value of a structure consists of the zero value of its members. Generally, zero is a default natural and reasonable value.
26 type Test struct { 27 Size int 28 Buffer string 29 IsBool bool 30 Mut sync.Mutex 31 } 32 33 func main() { 34 t1 := Test{} 35 fmt.Printf("%#v\n", t1) 36 }
The operation results are as follows
The zero value of the first three members of the struct type Test. The zero value of the integer type is 0. The zero value of the member of the string type is an empty string. The zero value of the member of the boolean type is false and sync A member of type mutex is a mutex that can be used directly and in an unlocked state.
3) Initializes a structure variable with a structure literal
One way is to specify a value for each member variable in the correct order, such as p1. This method is applicable to small structures that are easy to understand, such as Point type structures.
Another way is to initialize structure variables by specifying the names and values of some or all member variables, such as p2. This method is generally used more.
8 type Point struct { 9 X float64 10 Y float64 11 } 12 13 func main() { 14 p1 := Point{3.0, 4.0} 15 p2 := Point{X: 2.0, Y: 5.0} 16 17 fmt.Printf("%v\n", p1) 18 fmt.Printf("%v\n", p2) 19 }
Initializes a pointer to a structure variable
20 pp := &Point{5, 8} 21 fmt.Printf("%v\n", *pp)
This is equivalent to
23 pp2 := new(Point) 24 *pp2 = Point{5, 8} 25 fmt.Printf("%v\n", *pp2)
& point {5, 8} This method can be used directly in an expression, such as a function call.
IV visit
Each member of the structure can be accessed through a dot, or the address of the member variable can be obtained, and then it can be accessed through a pointer.
h1 , accesses the member , Age through the dot, and h1 modifies the value of the member variable , Height , through the pointer.
19 func main() { 20 h1 := Human{"Jim", 21, 65} 21 22 h1.Age++ 23 *(&h1.Height) += 2.0 24 fmt.Printf("%#v\n", h1) 25 }
The operation results are as follows
V compare
If all member variables of a structure can be compared, the structure is comparable. The comparison of two structures can use = = or! === The operator compares the member variables of two struct variables in order.
The statements in lines 28 and 29 are equivalent
26 p1 := Point{1, 2} 27 p2 := Point{2, 1} 28 fmt.Printf("%t\n", p1.X == p2.X && p1.Y == p2.Y) 29 fmt.Printf("%t\n", p1 == p2)
All comparable types can be used as the key type of map , and the structure variable addr , can be used as the key value of the map , variable acce ss ,
19 type address struct { 20 Ip string 21 Port string 22 } 23 24 func main() { 25 addr := address{"127.0.0.1", "9090"} 26 acce := make(map[address]int) 27 acce[addr]++ 28 fmt.Printf("%v\n", acce) 29 }
The operation results are as follows
Vi use
1) Function parameters
Generally, pointer transfer is used. First, it is for efficiency reasons. Second, # it is necessary when structural variables are required.
Value passing, a copy of the argument received by the caller, not a reference to the argument.
2) Structure nesting and anonymous members
a. Structure nesting, this mechanism allows us to use a named structure as an anonymous member of another structure type, and provides a convenient access method.
Using the example in the book and the following example code, the named structure is nested in the structure. When accessing the members in the structure variable w, the intermediate structure variable is used.
8 type Point struct { 9 X int 10 Y int 11 } 12 13 type Circle struct { 14 Center Point 15 Radius int 16 } 17 18 type Wheel struct { 19 Circle Circle 20 Spokes int 21 } 22 23 func main() { 24 var w Wheel 25 w.Circle.Center.X = 2 26 w.Circle.Center.Y = 3 27 w.Circle.Radius = 5 28 w.Spokes = 10 29 fmt.Printf("%#v\n", w) 30 }
In Go , you can define structure members without names. You only need to specify the type; This structure member is called an anonymous member. The structure member must be a named type or a pointer to a named type.
8 type Point struct { 9 X int 10 Y int 11 } 12 13 type Circle struct { 14 Point 15 Radius int 16 } 17 18 type Wheel struct { 19 Circle 20 Spokes int 21 } 22 23 func main() { 24 var ww Wheel 25 ww.X = 2 26 ww.Y = 3 27 ww.Radius = 5 28 ww.Spokes = 10 29 fmt.Printf("%#v\n", ww) 30 31 var w Wheel 32 w.Circle.Point.X = 2 33 w.Circle.Point.Y = 3 34 w.Circle.Radius = 5 35 w.Spokes = 10 36 fmt.Printf("%#v\n", w) 37 38 }
There is an anonymous member in Circle , Point and an anonymous member in Wheel , Circle. Structure variables ww# can directly access the required member variables without specifying a large string of intermediate variables. The method of accessing members of structure variable w # is also correct. You can see that this method is relatively cumbersome.
The operation results are as follows
b. Initialization of nested structures
Same as before. One is to initialize in order, and the other is to initialize with the name and value of member variables.
23 func main() { 24 w := Wheel{Circle{Point{3, 4}, 5}, 10} 25 fmt.Printf("%v\n", w) 26 27 ww := Wheel{ 28 Circle: Circle{ 29 Point: Point{ 30 X: 3, 31 Y: 4, 32 }, 33 Radius: 5, 34 }, 35 Spokes: 10, 36 } 37 fmt.Printf("%v\n", ww) 38 }
The printing results of the two methods are consistent
The last commas in lines 31, 33 and 35 need to be brought, otherwise an error will be reported during compilation.
c. Anonymous members are not necessarily struct types. Any named type or pointer to a named type can be used.
The members ¢ Ages ¢ and ¢ Weight ¢ in the structure type ¢ MyType ¢ are user-defined types, Name ¢ is a built-in type, and ContactInfo ¢ is a nested structure type.
23 type Ages int 24 type Weight float64 25 26 type ContactInfo struct { 27 Addr string 28 PhoneNum string 29 } 30 31 type MyType struct { 32 Name string 33 Ages 34 Weight 35 ContactInfo 36 } 37 38 func main() { 39 var t1 MyType 40 t1.Ages = 20 41 t1.Weight = 55 42 t1.Name = "Bob" 43 t1.Addr = "BeiJing" 44 t1.PhoneNum = "18888888888" 45 fmt.Printf("%v\n", t1) 46 }
The printing results are as follows
Internal variables that access anonymous members in a shortcut also apply to internal methods that access anonymous members. Therefore, the peripheral structure type obtains not only the internal variables of anonymous members, but also related methods.