1, define a structure body
Type User struct {userid int username string Password String}
2. Initialize a struct
There are two cases, one is to get the object of the structure, the first is to get the structure of the object pointer, respectively, there are three ways:
//the 1th way, first declare the object, then initialize var player1 Player player1.userid = 1 player1.username = "Lina1" player1.password = "123456" //2nd way, declaring simultaneous initialization player2 := Player{2, "Lina2", "123456"} //3rd way, through field:value form initialization, this way you can flexibly initialize the order of the fields player3 := player{username: "Lina3", password: "123456", userid: 3} //above three kinds of initialization methods are production objects, The three ways to initialize an object pointer are as follows: //1th way, use new keyword player4 := new (Player) player4.userid = 4 player4.username = "Lina4" player4.password = "123456" //the 2nd way, declaring simultaneous initialization of player5 := &player{5, "Lina2", "123456"} //3rd way through field: value form initialization, this mode can be flexible to initialize the order of the fields player6 := &Player{username: "Lina3 ", password: " 123456 ", userid: 6}
3. The difference between an object and an object pointer (rather, a value type and a pointer type)
Similar to C + +, the Go language also has pointers to objects and objects, but unlike the go language, operators do not invoke the members that the pointer belongs to, and are used as normal objects. To invoke.
For a function (or method), if the argument (or receiver) of the function is an object pointer, it means that the object can be modified, and conversely, if it is an object, the representation is non-modifiable (but if the object itself is a reference type, such as Map\func\chan, it is inherently modifiable). So the general practice is that the receiver of the method habitually uses object pointers rather than objects, on the one hand can be modified when the object is to be modified, on the other hand, it also reduces the cost of copying the parameters.
In addition, it is particularly special, if it is a function of the parameters, when the function is defined, is the use of objects or object pointers, there is an essential difference, in the use of objects as parameters of the function, cannot pass in the object pointer, similarly, in the use of object pointers as parameters of the function, also cannot pass in the object, or the compiler However, if it is a method, the recipient is defined as an object or an object pointer, and can receive calls to objects and object pointers. Let's define the relevant functions and methods as follows:
Incoming Player object parameter Func print_obj (player player) { // player.username = "new"//modification does not affect the incoming object itself log. Println ("userid:", player.userid)}//incoming Player object pointer parameters func print_ptr (player *player) { player.username = "New" log. Println ("userid:", player.userid)}//the recipient as a method of the Player object, the variable of the method receiver, in general without the GO language habit this/self instead, use the first lowercase letter of the recipient type to see the code style in the standard library. func (P player) m_print_obj () { //p.username = "new"// The modification does not affect the incoming object itself log. Println ("Self userid:", p.userid) } //the receiver as a method of the Player object pointer func (p * Player) m_print_ptr () { p.username = "new" log. Println ("Self userid:", p.userid) }
Then test the invocation of the function with the method:
Print_obj (Player2)//print_ptr (PLAYER2)//cannot be called, compilation Error Player2.m_print_obj () player2.m_print_ptr ()//print _obj (PLAYER6)//cannot be called, compilation Error print_ptr (PLAYER6) player6.m_print_obj () player6.m_print_ptr ()
Now that the object is different from the pointer to the object, the method's handling is very special, then passing an object into a method where the receiver is the object pointer, and passing an object pointer to a method that the receiver is an object, can you modify the value of the incoming object? The answer is that it is determined by the definition of the method, not by the caller type of the method.
4. Anonymous fields
A field in a struct can have only a type name, without a field name, which is called an anonymous field. An anonymous field can be a composite type, such as a struct, a slice, or a simple type such as int. However, it is not recommended to use a simple type as an anonymous field.
type pet struct { id int petname string}type Player struct { id int pet int}func main () { var player1 player player1.petname = "Pet1" //can access members in the anonymous field directly, Just like visiting your own members player1.int = 3 //generally do not recommend the simple type as an anonymous field, if there are multiple anonymous int, there is no way to handle the player1.id = 1 //If the outer layer is duplicated with the inner field name, take precedence over the outer field Player1. pet.id = 10 //If the outer layer is duplicated with the inner field name, you can access the inner field in this form}
A struct type named S will no longer contain members of type S: because an aggregated value cannot contain itself. (The restriction also adapts to arrays.) However, the struct of type S can contain *S members of the pointer type, which allows us to create recursive data structures such as linked lists and tree structures.
If the structure does not have any members, it is an empty structure, writing struct{}. It has a size of 0 and does not contain any information, but it can still be valuable at times. Some go language programmers use map bands to emulate the set data structure, instead of the Boolean type of value in the map, just emphasize the importance of key, but because the space is limited, and the syntax is more complex, we usually avoid this usage.
seen : = make (map[string]struct{}) //set of Strings// ... if _, OK: = Seen[s];!ok { seen[s] = struct{}{} //... first time seeing s ...}
Structs can function as parameters and return values, and if the structure is large, pointer parameters are generally used, and if you want to modify the structure in a function, you must use a pointer form. All function parameters in the Go language are copies of values.
If all members of a struct are comparable, the struct can also be compared, which can be used as the key type of the map.
Proud of the anonymous embedding feature, we can directly access the leaf properties without having to give the full path:
var W wheelw.x = 8//equivalent to W.circle.point.x = 8w. Y = 8//equivalent to W.circle.point.y = 8w. Radius = 5//equivalent to W.circle.radius = 5w. Spokes = 20
Unfortunately, struct literals do not have a short representation of the syntax of anonymous members, so the following statements cannot be compiled by:
W = wheel{8, 8, 5,//compile Error:unknown FIELDSW = Wheel{x:8, Y:8, Radius:5, spokes:20} Compile Error:unknown fields
So far, we have seen that anonymous member attributes provide short syntactic sugars only to the point operators that access nested members. Later, we will see that anonymous members are not required to be struct types, but any type of command can be an anonymous member of the struct. But why embed an anonymous member type that does not have any child member types?
The answer is an anonymous type of method set. The short point operator syntax can be used to select members that are nested in anonymous members, or to access their methods. In fact, the outer structure not only obtains all the members of the anonymous member type, but also obtains all the methods that the type exports. This mechanism can be used to combine an object with simple behavior into an object with complex behavior. Combination is the core of object-oriented programming in Go language
When you define a oxalate was, you can add a tag to each field, such as using the built-in JSON library. See metadata and reflection in detail.