“This is the 16th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

The structure of the body

Structs are aggregate data types that combine zero or more named variables of any type. Each variable is called a member of the structure.

type Employee struct {
    ID      int
    Name    string
    age     int
}
Copy the code

Employee is a structure.

Be careful when defining structures

1. A member variable is exportable if it begins with a capital letter.

2. The order of member variables is very important for the identity of the structure, and different orders indicate different structures.

3. The type of a member variable in a structure cannot be the structure itself, but can be a pointer to the structure

type Node struct {
    value   int
    next    *Node
    // This is illegal
    //next Node
}
Copy the code

4. The zero value of a structure consists of the zero values of its members.

Struct variable declaration

type Point struct {
    X   int
    Y   int
}

/ / way
p1 := Point{1.2} // X=1 Y=2
2 / / way
p2 := Point{X: 3, Y: 4} // X=3 Y=4

// If a member variable is not specified, the value of the member variable is zero
p3 := Point{Y:6} // X=0 Y=6
Copy the code

Mode one and mode two cannot be used together. And there is no way to bypass the rule that non-exportable variables cannot be used in other packages.

// p.go
package p
type T struct { a, b int }

// q.go
package q
import "p"
var _ = p.T{1.2}  // Error compiling
var _ = p.T{a: 1, b: 2} // Error compiling
Copy the code

If you need to modify the contents of a struct variable in a function, you need to pass a pointer

type Point struct {
	X, Y int
}

func update(p Point, x int) { // The function receives a copy of the real disaster
	p.X = x
}

func update2(p *Point, x int) {
	p.X = 2
}

func main(a) {
    p := Point{}
	update(p, 1)
	fmt.Println(p)  / / {0 0}
	update2(&p, 2)
	fmt.Println(p)  / / {2} 2
}
Copy the code

Comparison of structures

If all member variables are comparable, then the structure is mutable comparison

type Point struct {
	X, Y int
}

type Book struct {
	name     string
	chapters []string
}

func main(a) {
	p1 := Point{X: 1, Y: 2}
	p2 := Point{X: 1, Y: 2}
	p3 := Point{X: 1, Y: 3}
	fmt.Println(p1 == p2, p2 == p3)  // true false

	b1 := Book{name: "abc", chapters: []string{"1"."2"}}
	b2 := Book{name: "abc", chapters: []string{"1"."2"}}
	fmt.Print(b1 == b2) Chapters is a type of slice that cannot be compared
}
Copy the code

A structure has nested and anonymous members

The purpose of structure nesting is to reuse Go to allow us to define unnamed structure members (i.e., anonymous members) that can be quickly accessed to member variables within anonymous members

type Point struct {
	X, Y int
}

type Circle struct {
	Point
	Radius int
}

type Wheel struct {
	Circle
	Spokes int
}

func main(a) {
	var w Wheel
	w.X = 8         // equivalent to w.circle.point.x
	w.Y = 8
	w.Radius = 5    // equivalent to w.circle.radius
	w.Spokes = 20

	fmt.Printf("%#v", w) // main.Wheel{Circle:main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}, Spokes:20}
}

Copy the code

The outer structure Wheel gets not only the inner variables of the anonymous Circle member, but also the methods of the Circle

type Point struct {
	X, Y int
}

func (p Point) Print(a) {
	fmt.Printf("%#v", p)
}

type Circle struct {
	Point
	Radius int
}

func (c Circle) Print(a) {
	fmt.Printf("%#v", c)
}


type Wheel struct {
	Circle
	Spokes int
}

// func (w Wheel) Print() {
// fmt.Printf("%#v", w)
// }

func main(a) {
	var w Wheel
	w.X = 8
	w.Y = 8
	w.Radius = 5
	w.Spokes = 20

	fmt.Printf("%#v\n", w) // main.Wheel{Circle:main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}, Spokes:20}
	w.Print() // main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}
}
Copy the code

If you add an anonymously named member Band to the Wheel, it also has the Print method

type Band struct {
	Name string
}

func (b Band) Print(a) {
	fmt.Printf("%#v", b)
}

type Wheel struct {
	Circle
	Band
	Spokes int
}


func main(a) {
	var w Wheel
	w.X = 8
	w.Y = 8
	w.Radius = 5
	w.Spokes = 20

	fmt.Printf("%#v\n", w) // main.Wheel{Circle:main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}, Band:main.Band{Name:""}, Spokes:20}
	w.Print() // Compile error
    w.Circle.Print()  // main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}
    w.Band.Print()  // main.Band{Name:""}
}
Copy the code

If the outer Wheel structure has a Print method, that method is called directly. If it does not, but multiple anonymous members within it do, you need to display the Print method that specifies which anonymous structure to call