Hi, I’m Xingzhou, today we are going to learn the structure of Go language.

Structure is a complex data type, which is an important part of object-oriented programming in Go language.

Declarative structure

type animal struct {
    name string
    age int
    class string
    weight float32
}
Copy the code

As in the example above, the type keyword defines an animal type, and the struct after the animal type indicates that it is a structure. It has four fields, name, age, class, weight, and each field defines its corresponding type.

type animal struct {
   name,class string
   age int
   weight float32
}
Copy the code

As in the example above, we can separate fields of the same type on a single line with commas, but this is not readable and is not recommended.

Anonymous fields

type person struct {
   string
   int
}
Copy the code

When we define a structure field, we can define only the type without the name, which means that the name and type are the same, so the above is equivalent to:

type person struct {
   string string
   int int
}
Copy the code

Basic usage

Initialize the

type animal struct {
   name string
   age int
   class string
   weight float32
}

func main(a){
   var a1 animal // Initialize, each field corresponds to the default value of zero
   var a2 = animal{"Prosperous wealth.".2."Dog".12.8// Initialize and assign values in field order
   var a3 = animal{name:"Tom",age:3,weight:11.5,class:"Cat"// Initialize and display assignments to all fields
   var a4 = animal{name:"Black",age:5// Initialize, and display partial fields copied, unassigned fields with zero values corresponding to their types
a5 := struct// Anonymous structure, defined and initialized
   name string
   height float32
}{
   name: "SAN MAO",
   height:1.85,
}

   fmt.Printf("a1=%+v \n",a1) // print a1={name: age:0 class: weight:0}
   fmt.Printf("a2=%+v \n",a2) // print a2={name: print age:2 class: print dog weight:12.8}
   fmt.Printf("a3=%+v \n",a3) // print a3={name:Tom age:3 class: cat weight:11.5}
   fmt.Printf("a4=%+v \n",a4) // print a4={name: print age:5 class: weight:0}
   fmt.Printf("a5=%+v \n",a5) // print a5={name: height:1.85}
}
Copy the code

In the example above, A1, A2, A3, a4 show the four initializing structures and their print structures respectively.

For a1, when a field in the structure is not assigned, the default value is zero of the corresponding type of the field; For A2, if the specified field is not displayed, the assignment order must be the same as the field order. A5 differs from the previous four in that it declares and initializes an unnamed structure, which we call anonymous.

Modify the value

We can get the field value of a struct object with the dot sign, and we can also modify the field value. The following is an example:

type animal struct {
   name string
   age int
   class string
   weight float32
}

func main(a)  {
   a1 := animal{name:"Tom",age:3,weight:11.5,class:"Cat"}
   fmt.Printf("a1.age=%d \n",a1.age) // print a1.age=3

   a1.age = 5
   fmt.Printf("a1.age=%d \n",a1.age) // print a1.age=5
}
Copy the code

Initialize to a pointer type

type animal struct {
   name string
   age int
   class string
   weight float32
}

func main(a)  {
   a1 := &animal{name:"Tom",age:3,weight:11.5,class:"Cat"}
   fmt.Printf("a1.name=%s \n",a1.name) // print a1.name=Tom
   fmt.Printf("a1.name=%s \n",(*a1).name) // print a1.name=Tom
}
Copy the code

In the example above, a1 is assigned to the pointer type of the Animal structure. A1. Name and (*a1). Name have the same value, because Go language helped us to do the default type conversion, Go language found a1 is a pointer type, automatically help us to convert to the pointer value, so we can get the correct result through A1.

In Go, the ampersand is used to get the address and the * is used to get the pointer.

Structure nesting

type animalName struct {
   firstName string
   lastName string
}

type animal struct {
   animalName
   age int
   class string
   weight float32
}

func main(a)  {
   a1 := animal{
      animalName: animalName{
         firstName:"tom",
         lastName:"steven",
      },
      age: 5,
      class:"Cat",
      weight:12.5,
   }

   fmt.Printf("a1= %+v \n", a1) // print a1= {animalName:{firstName: Tom lastName: Steven} age:5 class: cat weight:12.5}
   fmt.Printf("a1.firstName= %+v \n", a1.firstName) // print a1.firstName= tom
   fmt.Printf("a1.lastName= %+v \n", a1.lastName) // print a1.lastName= steven
}
Copy the code

As in the example above, the animal structure we declared has an animalName structure nested within it. The structures a1.firstName and A1.lastName print are the field values of the animalName structure.

This is a property of nested structures that searches “deeper” into the nested structure when the structure’s own field does not exist. Go language search layer by layer, find the corresponding field to return its value, and stop the search.

An error is reported when two nested structures at the same level have the same field name, because Go does not know which structure’s fields should be accessed. The following is an example:

type animalName struct {
   firstName string
   lastName string
}

/ / animals
type animal struct {
   animalName
   age
   class string
   weight float32
}

type age struct {
   firstName string
   lastName string
}

func main(a)  {
   a1 := animal{
      animalName: animalName{
         firstName:"tom",
         lastName:"steven",
      },
      age: age{
         firstName:"age-tom",
         lastName:"age-steven",
      },
      class:"Cat",
      weight:12.5,
   }

   fmt.Printf("a1= %+v \n", a1) // print a1= {animalName:{firstName: Tom lastName: Steven} age:5 class: cat weight:12.5}
   fmt.Printf("a1.firstName= %+v \n", a1.firstName) // print a1.firstName= tom} Error: Ambiguous reference'firstName' 
Copy the code

We define the Animal structure, which has nested animalName and Age structures with firstName and lastName fields. Executing a1.firstName returns an error because two firstName fields were found in the second nested structure, and Go does not know which one to return. If you need to get the value of a nested structure, you need to specify the call path, as shown in the following example:

fmt.Printf("a1.animalName.firstName= %+v \n", a1.animalName.firstName) // print a1.animalName.firstName= tom
fmt.Printf("a1.age.firstName= %+v \n", a1.age.firstName) // print a1.age.firstName= age-tom
Copy the code

If the name of a field is not the same as the name of the field in the same level, the access will not fail. However, you should also know the priority of the access. When the inner structure of the field needs to be accessed, it is best to strictly write “call path”.

Sentenced to operations such as

Structs are value types. Structures can be compared if each field of two structures can be compared, whereas structures cannot be compared as long as one field cannot be compared. Two structures are equal only if all fields have the same value. Consider the following two examples:

type animal struct {
   name string
   age int
   class string
   weight float32
}

func main(a)  {
   a1 := animal{
      name: "tom",
      age: 5,
      class:"Cat",
      weight:12.5,
   }
   a2 := animal{
      name: "tom",
      age: 5,
      class:"Cat",
      weight:12.5,
   }

   fmt.Printf("A1 equals A2 %+v \n", a1 == a2) // print a1 = a2 true
}
Copy the code
type person struct { character map[string]string } func main() { a3 := person{ character: map[string]string{ "xinqing":"gaoxing", }, } a4 := person{ character: Map [string]string{"xinqing":"gaoxing",},} FMT.Printf("a3 = a4 = % v \n", a3 == a4) // 错误 : Invalid operation: a3 == a4 (operator == not defined on person) }Copy the code

A1 and A2 can be compared because each field of animal can be compared; The character of the person field is of the map type and cannot be compared. Invalid operation: A3 == A4 (operator == not defined on person)

Empty structure

A structure type can also contain no fields, and a structure without any fields can make sense, that is, the structure type can have methods. The following is an example:

type animal struct{}func (a animal) toString(a){
   fmt.Printf("I am animal!"// print I am animal!
}
func main(a)  {
   a := animal{}
   a.toString()
}
Copy the code

More on the methodology in the next article.

scope

Structures can be accessed across packages when the first letter of a structure is capitalized. The same is true for struct fields, which can be accessed across packages when the first letter of the field is uppercase, and only within packages when lowercase. The following is an example:

type Animal struct {
   Name string
   Age int
   class string
   weight float32
}
Copy the code

Animal itself can be referenced across packages, and its Name and Age fields can be accessed in other packages, but calss and weight fields are not.

conclusion

This article mainly introduces the declaration method, basic usage and scope of structure. In practical programming, structure is an important part of object-oriented programming.

Invite attention to the public number: a row of weekly update technical articles, and we progress together.