go-结构体和方法

结构体类型的字面量由关键字type、类型名称、关键字struct,以及由花括号包裹的若干字段声明组成。
type Person struct {
    Name   string
    Gender string
    Age    uint8
}   
Person{Name: "Robert", Gender: "Male", Age: 33}  
键值对的顺序与其类型中的字段声明完全相同的话,我们还可以统一省略掉所有字段的名称
Person{"Robert", "Male", 33}
结构体类型的值字面量时可以只对它的部分字段赋值,甚至不对它的任何字段赋值。
这时,未被显式赋值的字段的值则为其类型的零值。
上述情况下,字段的名称是不能被省略的。
匿名结构体
编写一个结构体值的字面量时不需要先拟好其类型。这样的结构体字面量被称为匿名结构体。
与匿名函数类似,我们在编写匿名结构体的时候需要先写明其类型特征(包含若干字段声明),再写出它的值初始化部分。
p := struct {
    Name   string
    Gender string
    Age    uint8
}{"Robert", "Male", 33}
匿名结构体最大的用处就是在内部临时创建一个结构以封装数据,而不必正式为其声明相关规则。
而在涉及到对外的场景中,我强烈建议使用正式的结构体类型。
结构体类型可以拥有若干方法(注意,匿名结构体是不可能拥有方法的)
所谓方法,其实就是一种特殊的函数。它可以依附于某个自定义类型。
方法的特殊在于它的声明包含了一个接收者声明。
这里的接收者指代它所依附的那个类型。名为Grow的方法的声明:
func (person *Person) Grow() {
    person.Age++
} 
p := Person{"Robert", "Male", 33}
p.Grow()  
最后,结构体类型属于值类型。
它的零值并不是nil,而是其中字段的值均为相应类型的零值的值。
结构体类型Person的零值若用字面量来表示的话则为Person{}。
package main

import (
    "fmt"
)

type Persion struct {
    name string
    age  int
    sex  byte
}

type Student struct {
    Persion //结构体匿名字段,只有类型,没有名字,匿名字段,继承了Persion的成员
    int     //基础类匿名字段
    id      int
    addr    string
    name    string
}

func main() {
//直接定义一个对象 var xx Student xx.name = "xiao x" //结构体中的其他结构体同名字成员变量, 需显示的调用赋值 xx.Persion.name = "xiao xie" xx.age = 100 fmt.Println(xx) //顺序初始化,匿名变量的初始化 var xiaoming Student = Student{Persion{"xiaoming", 20, 'm'}, 1, 100, "201 Room", "xx"} fmt.Println(xiaoming) //可直接使用匿名对象的类型 fmt.Println(xiaoming.int) //自动推导 xiaofang := Student{Persion{"xiaofang", 18, 'f'}, 1, 100, "401 Room", "xx"} fmt.Println(xiaofang) //指定成员初始化 s3 := Student{Persion: Persion{"xiaofang", 18, 'm'}} fmt.Println(s3) s4 := Student{addr: "203 Room"} fmt.Println(s4) }
type Student struct {
    *Persion //指针类型匿名字段
}

func main() {
    //方式1
    var xiaoming Student = Student{&Persion{"xiaoming2", 20, 'm'}}
    fmt.Println(xiaoming.name)

    //方式2
    var xiaofang Student
    xiaofang.Persion = new(Persion)
    xiaofang.Persion.name = "xiaofang"
    fmt.Println(xiaofang.Persion.name)
}
//带有接收者的方法叫成员函数
func (p Persion) PrintName() {
    fmt.Println(p)
}

//指针接收者
func (p *Persion) setName(str string) {
    p.name = str
}

func main() {
    var p Persion = Persion{"xiaoming", 10, 'M'}
    p.PrintName()
    (&p).setName("xiaof")
    p.PrintName()
}