Go语言基础、实战 -- 8. 结构体

1. 什么是结构体?

    结构体是自定义的类型,是若干字段的集合。

2. 结构体的定义

    具名结构体:

type Person struct {
    First_name 	string
    Last_name 	string
    age         int			// 开头为小写,不能被其它的包使用
    Sex         bool
}

    匿名结构体:

person_1 := struct {
    name    string
    age     int
    sex     bool
}{"Robinho", 25, true,}
fmt.Println(person_1)		//输出:{Robinho 25 true}

    这种写法并没有定义一种新的结构体类型,而是仅仅创建了一个新的结构体变量。

    在实际开发过程中很少有需要用这种写法。

3. 结构体变量声明(写字段,不写字段)

    写字段名,顺序可以与结构体字段声明的顺序不同:

person_3 := Person{
    Last_name   :   "Iverson",
    First_name  :   "Allen",
    sex         :   true,
    Age         :   25,
}
fmt.Println(person_3)		//输出:{Allen Iverson 25 true}

    不写字段名,顺序必须保持一致:

person_4 := Person{"Allen","Iverson",25,true}
fmt.Println(person_4)		//输出:{Allen Iverson 25 true}

4. 匿名字段

    在定义结构体时,我们也可以仅仅指定字段类型而不指定字段名字,这种字段叫做匿名字段。

    注意:一个类型只能出现一次,重复会报错。

    匿名字段虽然没有指定名字,但它有一个默认的名字,就是类型名:

type Club struct {
    string	// 名字
    int		// 冠军数量
}
var rng Club
rng.int = 8
rng.string = "RNG"    // 匿名字段,默认字段名就是类型名
fmt.Println(rng)      //输出:{RNG 8}

    不过这种实际用处也不是很大,即使只有一两个字段,还是给个字段名更直观一点,没必要偷这种懒。

5. 结构体嵌套

    结构体是可以嵌套的:

type Player struct{
    Name    string
    Age     int
    club    Club
}
info := Player{
    Name    : "Uzi", 
    Age     : 23, 
    club    : Club {"RNG", 8},
}
uzi.club.int = 9             // 如果要使用被嵌套的结构体中的字段,必须这样写
fmt.Println(info)            // 输出结果为:{Uzi 23 {RNG 9}}

6. 字段提阶

    结构体嵌套,如果想使用被嵌套的结构体中的字段,必须通过被嵌套结构体的字段名,这样不是很方便。

    所以我们可以将被嵌套的结构体声明为匿名字段,来实现字段提阶,被嵌套结构体中的字段就成了提阶字段,这样就可以直接用这些字段了,仿佛这些字段本身就是属于外部结构体一样。

type Address struct{
    City        string
    Province    string
}
type Brand struct {
    Name        string
    Industry    string
    Address
}
laoganma := Brand{}
laoganma.Name = "LaoGanMa"
laoganma.Industry = "Food"
laoganma.City = "GuiYang"
laoganma.Province = "GuiZhou"   // 提阶字段,可以直接使用
fmt.Println(laoganma)           // 输出结果为:{LaoGanMa Food {GuiYang GuiZhou}}

    

7. 结构体的初始值

    如果结构体变量没有被初始化,那么它各个字段的初始值就是各自类型的零值。

player := Player{}
fmt.Println(player)				// 输出结果为:{ 0 { 0}}

8. 结构体的比较

    -- 结构体是值类型的,如果其字段是可以比较的,那么该结构体就是可以比较的,直接用 == 操作符来比较即可。

    -- 如果结构体包含不可比较的字段,那么这个结构体类型是不可以比较的。

    -- 如果两个结构体变量中的非空字段都相等,则认为这两个结构体变量相等。

player1 := Player{"", 23, Club{"RNG", 8}}
player2 := Player{"", 23, Club{"RNG", 8}}
if player1 == player2 {
    fmt.Println("player1 == player2")        // 此句代码被执行
}

9. 导出结构体和字段

    回顾一下,在导入包的部分提到过,函数和包级别的变量想要被导出,命名必须以大写开头。

    结构体同样如此!

    结构体中的字段同样如此!!

10. String()函数

    对于一个自定义类型,如果实现了String()方法,那么fmt默认会调用String()。

    实际上就相当于自己定义了一个自定义类型怎么被fmt打印输出。

    例子可以看上一篇 指针 中的Human结构体。

原创文章 20 获赞 15 访问量 1万+

猜你喜欢

转载自blog.csdn.net/zhounixing/article/details/105841299