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 知识来解决实际问题。

相关推荐
狂奔小菜鸡2 小时前
Day29 | Java集合框架之Map接口详解
java·后端·java ee
沐知全栈开发2 小时前
《jQuery 密码验证》
开发语言
爱学习的小可爱卢2 小时前
JavaEE进阶——Spring事务与传播机制实战指南
java·java-ee·事务
-大头.2 小时前
Java泛型实战:类型安全与高效开发
java·开发语言·安全
周杰伦_Jay2 小时前
【操作系统】进程管理与内存管理
java·数据库·缓存
charlie1145141912 小时前
现代C++工程实践:简单的IniParser4——实现ini_parser
开发语言·c++·笔记·学习·工程
捧 花2 小时前
Go Web 中 WebSocket 原理与实战详解
网络·后端·websocket·网络协议·http·golang·web
serendipity_hky2 小时前
【SpringCloud | 第3篇】Sentinel 服务保护(限流、熔断降级)
java·后端·spring·spring cloud·微服务·sentinel
Kiri霧2 小时前
Go 切片表达式
java·服务器·golang