Go 结构体 ,struct

结构体就是一个复杂的数据类型,里面可以包含字段,也可以嵌套其他结构体

Go 中没有 class,可以使用 struct 代替

声明

通过 type she

type struct_name struct {
        field_name1 field_type1
        field_name2 field_type2
}

示例:

type student struct {
        Name string
        Age int
        score int
}

实例化

结构体有 3 种实例化方式

// 直接初始化
var stu student

// 通过 new 进行初始化
var stu *student = new(student)
stu := new(student)

// 赋值初始化
stu := student{}

// 等效于 stu := new(student)
var stu *student = &student{}
stu := &student{}

访问

通过 . 可以访问到结构体内的字段

指向结构体的指针也可以直接访问

(*struct_name).field_name == struct_name.field_name

储存结构

结构体内部储存的数据在内存中都是连续的

tag

由于 Go 中限制只有以大写字母开头的才能在其他包中访问到

可以通过 tag 使得指定包中获取到的名称

示例:

// 小写字母开头的无法在其他包中访问
type student1 struct {
        Name string
        Age int
        score int
}

// 设置 tag 使得 json 包中访问数据可以自定义
type student2 struct {
        Name string `json:"name"`
        Age int `json:"age"`
        Score int `json:"score"`
}
func jsonTest() {
        stu1 := student1{
                Name:  "Tom",
                Age:   18,
                score: 90,
        }

        stu2 := student2{
                Name:  "Tom",
                Age:   18,
                Score: 90,
        }

        res, err := json.Marshal(stu1)
        if err != nil {
                fmt.Printf("some error occured: %v", err)
        } else {
                fmt.Printf("student1: %s\n", string(res))
        }

        res, err = json.Marshal(stu2)
        if err != nil {
                fmt.Printf("some error occured: %v", err)
        } else {
                fmt.Printf("student2: %s\n", string(res))
        }
}

输出结果:

student1: {"Name":"Tom","Age":18}
student2: {"name":"Tom","age":18,"score":90}

匿名字段

定义结构体时,可以省略字段名只写类型,这样就定义了一个匿名字段

由于结构体中字段名必须时唯一的,所以匿名的类型也必须是唯一的

示例:

type foo struct {
        field1 int
        string
}

func main() {
        bar := foo{}
        bar.field1 = 1
        bar.string = "hello world"
        fmt.Printf("%v", bar)
}

结构体嵌套

在结构体中嵌套结构体时使用匿名字段可以更加简便获取内层结构体的字段

当 内层结构体的字段 和 外层结构体的字段 没有重复时可以直接获取,如果有重复时需要加上 内层结构体名 才能正常获取

这就是 Go 实现继承的方式

匿名字段访问示例:

type foo struct {
        field1 int
        field2 string
}

type bar struct {
        foo
        field1 string
        field3 int
}

func main() {
        foobar := bar{}
        foobar.foo.field1 = 1
        foobar.field2 = "hello"
        foobar.field1 = "world"
        foobar.field3 = 2
        fmt.Printf("%v", foobar)
}

输出结果:

{{1 hello} world 2}

如果没有使用匿名字段,这时就是组合,即使 内层结构体的字段 和 外层结构体的字段 没有重复时也不能省略结构体名

组合

组合和嵌套匿名结构体相似,但是结构体名称不能省略