Go 结构体

Go 语言有几种用于存储多个元素的数据类型,例如数组(array)和切片(slice);但是,它们不能同时存储不同类型的值!当我们在 Go 程序中需要组合不同类型的变量时,就应该使用 struct 数据类型。

在本节中,我们将学习 Go 的 struct:如何声明和初始化它们,如何访问其中的数据,以及如何比较两个 struct 是否相等。


什么是 struct?

struct(结构体的缩写)是一种数据类型,它允许我们将不同类型的元素组合在一起,例如整数、字符串、map,甚至其他 struct,形成一个单独的类型。任何具有一系列属性的现实世界实体都可以用 struct 来表示。

如果你熟悉 Java 或 C++,struct 可以与这些面向对象语言中的类(class)相比较。Go 的 struct 可以被视为一种轻量级类(lightweight class),它不支持继承,但支持组合(composition)。


声明 struct

下面我们声明一个 Animal 结构体:

type Animal struct {
    Name        string
    Class       string
    Emoji       string
    avgLifespan int
    Domestic    bool
}

解释代码
在这段代码中,type 关键字用于定义新的结构体类型;紧接着是结构体名称 Animal,然后是 struct 关键字。大括号 {} 内部是字段列表,每个字段都有名字和类型。

我们还可以将相同类型的多个字段写在一行:

type Animal struct {
    Name, Class, Emoji string // 一行定义所有 string 类型字段
    avgLifespan        int    
    Domestic           bool
}

初始化 struct

声明了 Animal struct 之后,我们可以给它初始化数据,也可以访问它的字段。常见的初始化方式有三种:

1. 基本初始化
var crocodile Animal

解释代码
这会创建一个 Animal 类型的局部变量 crocodile,所有字段会被设置为默认值(字符串为空,int 为 0,bool 为 false)。

2. 使用 new 函数
crocodile := new(Animal)

解释代码
new 函数为 struct 分配内存,将字段设置为默认值,并返回一个指向 struct 的指针(*Animal)。

3. 使用 struct 字面量
crocodile := Animal{
    Name: "Crocodile",
    Class: "Reptile",
    Emoji: "🐊",
    avgLifespan: 55,
    Domestic: false,
}

fmt.Printf("%#v", crocodile)
// 输出:main.Animal{Name:"Crocodile", Class:"Reptile", Emoji:"🐊", avgLifespan:55, Domestic:false}

解释代码
通过 struct 字面量,我们可以直接给每个字段赋值,初始化 struct。


访问和赋值 struct 字段

初始化 struct 后,可以使用 . 操作符访问字段:

fmt.Println("Animal name:", crocodile.Name)
fmt.Println("Class:", crocodile.Class)
fmt.Println("Emoji representation:", crocodile.Emoji)
fmt.Println("Average lifespan in years:", crocodile.avgLifespan)
fmt.Println("Is this animal domestic?", crocodile.Domestic)

// 输出:
// Animal name: Crocodile
// Class: Reptile
// Emoji representation: 🐊
// Average lifespan in years: 55
// Is this animal domestic? false

同样,也可以对已初始化的 struct 单独赋值:

var octopus Animal // 声明并初始化新的 Animal 类型 struct

octopus.Name = "Octopus"
octopus.Class = "Cephalopod"
octopus.Emoji = "🐙"

struct 的比较与相等性

如果两个 struct 属于同一类型,并且所有字段的值相等,它们可以使用 == 运算符进行比较。示例:

type Person struct {
    Name string
    Age  int
}

// 声明并初始化三个 Person struct
jerry1 := Person{Name: "Jerry", Age: 37}
jerry2 := Person{Name: "Jerry", Age: 37}
jerry3 := Person{Name: "Jerry"} // jerry3 的 Age 字段未初始化

fmt.Printf("structs: jerry1 and jerry2 are equal is %t\n", jerry1 == jerry2)
fmt.Printf("structs: jerry1 and jerry3 are equal is %t", jerry1 == jerry3)

// 输出:
// structs: jerry1 and jerry2 are equal is true
// structs: jerry1 and jerry3 are equal is false

解释代码
虽然 jerry1、jerry2 和 jerry3 都是 Person 类型,但 jerry3 的 Age 字段未初始化,因此与 jerry1 比较时结果为 false。

注意,如果 struct 中包含无法用 == 比较的字段(例如 map 或 slice),则该 struct 变量不可比较。


总结

今天我们学习了很多内容,最重要的几点是:

  1. struct 的定义及初始化方法。

  2. 如何访问或赋值 struct 的单个字段。

  3. 如何比较两个 struct 是否相等。

接下来可以用所学的 struct 知识来解决实际问题。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值