Go basics: struct and nested struct

Source: Internet
Author: User
Struct

Struct defines the structure. The structure consists of fields. Each field has a data type. In a struct, each field name must be unique.

To put it bluntly, it is used to store data, but it is highly customizable and flexible in usage. Many functions of Go depend on the structure. This is just a role.

Objects are not supported in go. struct is the burden of describing classes in objects. This mode is called composite ). The relationship between parent class and Child class, class and object isis aFor exampleHorse is a AnimalThe combination in go is the relationship between the external struct and the internal struct, the relationship between the struct instance and the struct, they arehas a. Through the composite of struct in go, you can "imitate" Many object-oriented behaviors, they are "like ".

Define struct

The format for defining struct is as follows:

Type identifier struct {field1 type1 field2 type2 ...} // Or type T struct {a, B INT}

Theoretically, each field has a unique name. However, if you confirm that a field is not used, you can define its name as a null identifier._To discard:

type T struct {    _ string    a int}

Each field has a type and can be of any type, including the built-in simple data type, other custom struct types, the current struct type itself, interfaces, functions, channels, and so on.

If several fields have the same type, they can be abbreviated to the same row:

type mytype struct {    a,b int    c string}
Construct a struct instance

If struct is defined, a data structure, or data type, or a class is defined. All in all, when struct is defined, it can be used as an abstract template to generate a specific instance based on this abstract template, which is also called an "object ".

For example:

Type person struct {name string age int} // initialize a person instance var P person

Here, P is a specific person instance. It is constructed based on the abstract template person and has the specific attribute name and age values, although each of its fields is 0 during initialization. In other words, P is a specific person.

During struct initialization, the default 0 Initialization is performed, and each field of struct is assigned a corresponding 0 value based on their data type. For example, the int type is 0, the string type is "", and the reference type is nil.

Because p is an instance after the person initialization, it already has a real property (that is, a field), so you can directly access its attributes. Here, we use the access attribute method.p.FIELDAssign values to each field.

// Assign values to the attributes of the person instance and define the specific personp. Name = "longshuai" P. Age = 23

Get the value of an attribute:

FMT. println (P. Name) // output "longshuai"

You can also directly assign values to define the properties of struct to generate a struct instance. It will deduce the type of p Based on the value.

VaR P = person {name: "longshuai", age: 23} p: = person {name: "longshuai", age: 23} // No name assignment is given, it must be in the field order P: = person {"longshuai", 23} p: = person {age: 23} p. name = "longshuai"

If the attribute branch of struct is assigned a valueRequiredThe comma "," after each field cannot be omitted; otherwise, an error is returned. This makes it easy to remove and add attributes in the future:

P: = person {name: "longshuai", age: 23, // This comma cannot be omitted}

You can also use the new () function or&TYPE{}To construct a struct instance. It allocates memory for struct and performs default 0 initialization for each field. They are equivalent. They all return data object pointers to variables. In fact&TYPE{}The underlying layer will call New ().

P: = new (person) P: = & person {} // assign P. Name = "longshuai" P. Age = 23 to the property after the object is generated

Use&TYPE{}You can also initialize the value assignment method, but new () does not:

p := &person{    name:"longshuai",    age:23,}

Select New () or&TYPE{}How to construct an instance? They are completely random. They are equivalent. However, if you want to assign values during initialization, consider using&TYPE{}.

Struct value and pointer

The following three methods can be used to construct the person struct instance P:

p1 := person{}p2 := &person{}p3 := new(person)

However, P1 is different from P2 and P3, and the output shows the following:

package mainimport (    "fmt")type person struct {    name string    age  int}func main() {    p1 := person{}    p2 := &person{}    p3 := new(person)    fmt.Println(p1)    fmt.Println(p2)    fmt.Println(p3)}

Result:

{ 0}&{ 0}&{ 0}

P1, P2, and P3 are all person struct instances, but P2 and P3 are completely equivalent. They all point to the instance pointer, And the pointer stores the instance address, so the Pointer Points to the instance, and P1 points directly to the instance. The relationship between the three variables and the person struct instance is as follows:

Variable name pointer Data Object (Instance) --------------------------------- p1 (ADDR) -----------> {0} P2 -----> PTR (ADDR) --> {0} P3 -----> PTR (ADDR) --> {0}

So P1 and PTR (ADDR) Save the data object address, P2 and P3 Save the PTR (ADDR) address. Usually, the variables pointing to the pointer (P1, P2) are directly called pointers, and the variables directly pointing to the Data Object (P1) are called objects themselves, because the content pointing to the data object is the address of the Data Object, PTR (ADDR) and P1 both save the address of the Instance Object.

HoweverAlthough one is the data object Value and the other is the pointer, they are all instances of the data object.. That is to say,p1.nameAndp2.nameCan access the properties of the corresponding instance.

Thatvar p4 *personWhat is it? This statement indicates that P4 is a pointer, and it points to the object of the person type, but because it is a pointer, it will be initialized to nil, that is, it does not point to the target. But it has been clearly stated that P4 points to a pointer to the address of the data object to be saved. That is to say, so far, the directed relationship of P4 is as follows:

p4 -> ptr(nil)

Since p4 is a pointer&person{}Ornew(person)Assigned to P4.

var p4 *personp4 = &person{    name:"longshuai",    age:23,}fmt.Println(p4) 

The above code will be output:

&{longshuai 23}
Pass value or pointer

The go function replicates values to parameters.

When copying and passing values, if the function parameter is a struct object, a copy of the entire data structure will be copied directly to the function. There are two problems:

  • The function cannot modify the original data structure passed to the function. Only the copied copy of the original data structure is modified.
  • If the transmitted raw data structure is large, the overhead of completely copying a copy is not small.

Therefore, if conditions permit, the struct pointer should be passed to the function that requires the struct instance as a parameter. For example:

func add(p *person){...}

Since the pointer is to be passed, how does the struct pointer come from? Naturally&Symbol. You can create a successfully created instance or an instance that has not yet been created.

For struct instances that have been created successfullypIf the instance is a value rather than a pointer (That is, p-> {person_fields}), Then you can&pTo obtain the pointer of the existing instance and then pass it to the function, as shown in figureadd(&p).

You can use&person{}Ornew(person)Directly generate the instance pointer P. Although it is a pointer, go can automatically resolve it to an instance object. Then pass the pointer P to the function. For example:

p1 := new(person)p2 := &person{}add(p1)add(p2)
Tag attribute of struct Field

In struct, in addition to the name and data type, field can also have a tag attribute. The tag attribute is used for each field of "comment". In addition to the reflect package, this tag attribute cannot be used in normal programs.

type TagType struct { // tags    field1 bool   "An important answer"    field2 string "The name of the thing"    field3 int    "How much there are"}
Anonymous field and struct nesting

Fields in struct can be called anonymous Fields instead of names.The name of an anonymous field must be of the same type and type.. For example:

type animal struct {    name string    age int}type Horse struct{    int    animal    sound string}

The preceding horse has two anonymous fields.intAndanimalAnd its names and types are both int and animal. It is equivalent:

type Horse struct{    int int    animal animal    sound string}

Apparently, other struct (such as animal) are nested in the above horse ). Here, animal is called internal struct, and horse is called external struct.

The following is a simple example of nesting struct:

package mainimport (    "fmt")type inner struct {    in1 int    in2 int}type outer struct {    ou1 int    ou2 int    int    inner}func main() {    o := new(outer)    o.ou1 = 1    o.ou2 = 2    o.int = 3    o.in1 = 4    o.in2 = 5    fmt.Println(o.ou1)  // 1    fmt.Println(o.ou2)  // 2    fmt.Println(o.int)  // 3    fmt.Println(o.in1)  // 4    fmt.Println(o.in2)  // 5}

The aboveoIs an instance of outer struct,oBesides its own explicit fields ou1 and ou2, it also has int fields and inner fields, which are nested fields. Once nested, the internal struct attributes will also be obtained by the external struct, soo.int,o.in1,o.in2All belongo. That is to say,External struct has a internal struct, Orstruct has a field.

The outer instance above can also be directly assigned for construction:

o := outer{1,2,3,inner{4,5}}

The value of in1 and in2 in inner cannot be missing.inner{}Otherwise, in1 and in2 will directly belong to outer, rather than nested belongs to outer.

Obviously, struct Nesting is similar to Object-oriented Inheritance. The inherited relational model is "subclass is a parent class". For example, "a car is a car", while the nested struct relational model isExternal struct has a internal struct, As in the above exampleOuter has inner.

Name Conflict of nested struct

What if the field name in the external struct is the same as that in the internal struct?

There are two conflicting naming rules:

  1. The external struct overwrites the Same Name field and method of the internal struct.
  2. Returns an error when a field with the same name appears in struct at the same level.

The first rule allows go struct to override the object and rewrite fields and methods.

The second rule makes attributes of the same name unambiguous. For example:

type A struct {    a int    b int}type B struct {    b float32    c string    d string}type C struct {    A    B    a string    c string}var c C

According to rule (1), a and c directly under C will cover a. A and B. C respectively. C. a, C. c accesses fields A and C directly under C, and uses C. D or C. b. d. All accesses belong to nested B. D field. If you want to access the covered attributes in the internal struct, you can access them in the form of C. A..

According to rule (2), A and B are nested structures of the same level in C, so. B and B. B is in conflict and an error will be reported, because when C. B Does not know that C. a. B or C. b. b.

Go basics: struct and nested struct

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.