Writing in the front

In the previous article, “Golang functions for Beginners”, we learned how to use Golang functions. Next, we’ll look at the structure of Golang.

Definition of structure

Structs are similar to classes in other object-oriented concepts, but they are distinctly different from classes. Structures are composite types, which consist of a series of properties that correspond to different values and types. The data that makes up the structure type is called fields.

Golang supports user-defined types, or custom types, in the form of constructs.

Definition method:

type StructName struct {
	field1 type1
	field2 type2
    ...
}
Copy the code

Instantiation of a structure

Use the new ()

We can allocate memory to a new structure variable using the new function, which returns a pointer to the allocated memory.

var t *StructName
t = new(StructName)
Copy the code

Consider the following example:

First, we define a structure Immortal in the package go_code/struct/model, and introduce this package into main and use Immortal

go_code/struct/model/immortal.go:

package model

/ / cultivate immortality
type Immortal struct {
	Name string
	Age int
	Gender string
}
Copy the code

In the main:

package main

import (
	"go_code/struct/model"
	"strconv"
)

func main(a) {
	// I is a pointer to the variable of the Model. Immortal structure
	var i *model.Immortal
	i= new(model.Immortal)
	i.Age = 500
	i.Name = Mr.han ""
	i.Gender = "Male"

	println(i.Name, strconv.Itoa(i.Age)+"Age",i.Gender)

}

Copy the code

Output:

Han Li 500-year-old maleCopy the code

We can obtain or assign a value to a structure using point notation, which is called the select-notation in Golang.

Use mixed literal syntax

The shorter and more conventional way to initialize an instance of a structure is as follows:

// The type of I is * model.immortal
var i =  &model.Immortal{"Nangong Wan".18."Female"}

/ / or
var i model.Immortal
i := model.Immortal{"Nangong Wan".18."Female"}
Copy the code

The method used in these two examples (&model.Immortal{” nimmortal “,18,” female “}) is called composite Literal sysnTax, which is a shorthand that still calls the new function at the bottom. One thing to note in this notation is that the order of the values must be written in the order of the fields. The expressions new(Type) and &Type() are equivalent.

Characteristics of structures in Golang

Memory layout

In Go, a structure and the data it contains exist in memory as contiguous blocks, even if there are other structures nested within the structure, which gives a big performance advantage.

Recursive structure

A structure type can be defined by reference to itself. This is especially useful when defining elements of a linked list or binary tree (often called nodes) that contain links (addresses) to neighboring nodes.

package model

type Node struct {
	data string
	next *Node
}
Copy the code

Where, the data field stores the data of the current node, and next is the pointer to the next node

Transformation of structure

Type conversions in Go follow strict rules. When an Alias type is defined for a structure, both the structure type and its Alias type have the same underlying type.

Take a look at this example:

number.go

package model

type Number struct {
	Value float32
}
Copy the code

conversion.go:

package main

import "go_code/struct/model"

func main(a) {
	var a = myNumber{Value: 18.0}
	b := model.Number(a)
	println(b.Value)
}

type myNumber model.Number
Copy the code

Create a structure instance using the factory method

Golang does not support the same constructors as other object-oriented programming languages, such as Java. We typically create a struct instance by defining a construct factory method.

Look at the following example:

package model

/ / cultivate immortality
type Immortal struct {
	Name string
	Age int
	Gender string
}

func NewImmortal(age int, name, gender string) *Immortal {
	if age<0 {
		return nil
	}
	return &Immortal{Name: name,Gender: name,Age: age}
}

Copy the code

Factory method names, which typically start with New or New, return a pointer to an instance of the structure

How do I force the factory method instead of just new?

Before we talk about this, we need to add a little bit more information about the package visibility rules in Golang:

In Golang, identifiers (constants, variables, types, function names, structure fields, and so on) begin with a capital letter, such as: Group1, then objects using this form of identifier can be used by external package code (the client program needs to import the package first), which is called an export (like public in object-oriented languages); Identifiers that begin with a lowercase letter are not visible outside the package, but they are visible and available throughout the package (like private in object-oriented languages).

Therefore, for our purposes, we need to define our structure as follows:

package v2

type immortal struct {
	name string
	age int
	gender string
}

func NewImmortal(age int, name, gender string) *immortal {
	if age < 0 {
		return nil
	}
	
	return &immortal{
		name:   name,
		age:    age,
		gender: gender,
	}
}
Copy the code

Tagged structure

In addition to having a name and type, a field in a structure can have an optional tag: a string attached to a field that can be a document or other important tag. The contents of the tag cannot be used in normal programming; only the package Reflect retrieves it. Gorm (a Golng ORM framework similar to Mybatis in Java) uses tag tag fields to map database table fields.

Consider the following example:

package tag

import (
	"fmt"
	"reflect"
)

type Immortal struct {
	Name string "The name of the immortal."
	Age int "The age of the faery practitioner."
	Gender string "The sex of the faerie practitioner."
}


func PrintTag(im Immortal, i int) {
	imm :=reflect.TypeOf(im)
	value :=imm.Field(i)
	fmt.Println(value.Tag)
}
Copy the code
package main

import "go_code/struct/model/tag"

func main(a) {
	var immortal = tag.Immortal{Name: "Nangong Wan", Age: 18, Gender: "Female"}
	for i:=0; i<3; i++ {
		tag.PrintTag(immortal,i)
	}
}

Copy the code

Output:

The name of the apothecary the age of the apothecary the sex of the apothecaryCopy the code

Anonymous fields and embedded structures

A structure can contain one or more anonymous (or embedded) fields, that is, those fields have no explicit name, only the type of the field is required, in which case the type is the name of the field. An anonymous field can itself be a structure type, that is, a structure can contain an embedded structure. In Golang, inheritance in other object-oriented programming languages is implemented through composition.

Take a look at the following example

package main

import "fmt"

type immortal struct {
	/ / name
	string
	/ / age
	int
	// The realm of celestial cultivation
	level

}

type level struct {
	// The name of the realm
	string
	/ / reiki values
	float32
}

func main(a) {
	var im = immortal{
		string: Mr.han "".int:    500,
		level:  level{
			"Seven layers of qi training".7800.0,
		},
	}
	fmt.Println("====== Faery Practitioner information card ======")
	fmt.Println("Name:",im.string)
	fmt.Println("Age:",im.int)
	fmt.Println("------ Realm information ---------")
	fmt.Println("Boundary name:",im.level.string)
	fmt.Println("Realm Reiki value:",im.level.float32)
	fmt.Println("------ Realm information ---------")
	fmt.Println("====== Faery Practitioner information card ======")}Copy the code

Output:

====== Immortals information card ====== Name: Han Li Age:500------ Realm information --------- Realm name: Practicing Qi Seven-layer realm Reiki value:7800------ realm information --------- ====== Impostor information card ======Copy the code

Write in the last

That’s all for Golang structures, and the examples in this article can be downloaded here. If my study notes can help you, please give me a thumbs up and encouragement. If there are mistakes and omissions in the article, please help to correct them.