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 结构体:

go 复制代码
type Animal struct {
    Name        string
    Class       string
    Emoji       string
    avgLifespan int
    Domestic    bool
}

解释代码

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

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

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

初始化 struct

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

1. 基本初始化
go 复制代码
var crocodile Animal

解释代码

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

2. 使用 new 函数
go 复制代码
crocodile := new(Animal)

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

3. 使用 struct 字面量
go 复制代码
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 后,可以使用 . 操作符访问字段:

go 复制代码
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 单独赋值:

go 复制代码
var octopus Animal // 声明并初始化新的 Animal 类型 struct

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

struct 的比较与相等性

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

go 复制代码
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 知识来解决实际问题。

相关推荐
Cloud_Shy618几秒前
解读《Effective Python 3rd Edition》:从练气到老魔(第七章 Item 51)
开发语言·人工智能·笔记·python·学习方法
AI+程序员在路上几秒前
CSP、PP、PV、HM 在 CiA402 标准下的差异解析
linux·c语言·开发语言·嵌入式硬件
nix.gnehc1 分钟前
Python 并发深度解析
服务器·开发语言·python
我是一颗柠檬2 分钟前
【Java项目技术亮点】Leaf号段模式双Buffer优化
java·开发语言·分布式·后端·架构
Cx330❀5 分钟前
【MySQL基础】详解MySQL数据类型:底层原理、越界测试与最佳实践
linux·开发语言·数据库·c++·mysql
Volunteer Technology8 分钟前
Flink 时间、窗口及操作(二)
java·python·flink
星恒随风9 分钟前
C++ string 入门(一)
开发语言·c++·笔记·学习
skywalk816315 分钟前
继续推进心语项目6.15 @CodeArts
开发语言·算法·编程
程序员三明治19 分钟前
【AI】从文本到向量:理解Embedding的作用
java·人工智能·后端·llm·元数据·rag·向量化
嵌入式-老费19 分钟前
esp32开发与应用(看门狗测试)
java·开发语言·数据库