Go语言结构体和元组全面解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: Go语言结构体和元组全面解析

Go语言中的复合类型与其应用
在编程中,标准类型虽然方便,但无法满足所有需求。Go通过支持结构体和元组类型,为开发者提供了自定义数据类型的能力。本文将介绍如何定义结构体、如何使用指针操作结构体、如何通过元组返回多个值等内容,并结合实际示例展示这些功能的强大之处。

复合类型简介
Go的标准类型,如整型、浮点型等,虽然非常灵活和高效,但它们无法涵盖所有数据需求。当我们需要自定义复杂数据类型时,可以使用结构体。Go语言还提供了类似元组的支持,使得函数可以返回多个值,而无需像C语言那样将它们分组到结构体中。

结构体的使用
数组、切片和映射虽然实用,但它们无法将不同类型的数据聚合在一起。当需要将多个不同类型的变量组合成一个新类型时,结构体便派上用场。结构体的每个元素被称为字段。下面通过一个简单的例子来了解如何定义和使用结构体:

type aStructure struct {
person string
height int
weight int
}
1
2
3
4
5
这个结构体包含了三种不同的字段:person、height 和 weight。可以通过以下方式创建一个结构体变量:

var s1 aStructure
1
通过字段名称访问结构体中的某个值,例如:s1.person。

结构体字面量可以这样定义:

p1 := aStructure{"张三", 175, 65}
1
然而,为了避免记忆字段顺序的麻烦,Go允许我们在定义字面量时通过字段名来初始化:

p1 := aStructure{weight: 65, height: 175}
1
这种方式更加清晰,不必为每个字段都赋初始值。接下来展示一个更实用的例子。

结构体的实际应用
接下来,我们来看一个更复杂的例子structures.go,这个程序展示了如何在函数中定义结构体并操作它们。

package main
import (
"fmt"
)

func main() {
type XYZ struct {
X int
Y int
Z int
}

var s1 XYZ
fmt.Println(s1.Y, s1.Z)  // 输出结构体字段Y和Z的值

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在这个例子中,XYZ结构体类型被定义在main函数内部,这意味着它只能在当前函数内使用。虽然通常我们会在全局定义结构体以便整个包使用,但局部定义结构体有助于隔离作用域。

接下来,创建两个结构体实例并打印它们:

p1 := XYZ{23, 12, -2}
p2 := XYZ{Z: 12, Y: 13}
fmt.Println(p1) // 打印结构体p1
fmt.Println(p2) // 打印结构体p2
1
2
3
4
最后,展示如何将结构体存储在数组中:

pSlice := [4]XYZ{}
pSlice[2] = p1
pSlice[0] = p2
fmt.Println(pSlice) // 打印结构体数组
1
2
3
4
执行上述程序,输出结果如下:

0 0
{23 12 -2}
{0 13 12}
[{0 13 12} {0 0 0} {23 12 -2} {0 0 0}]
1
2
3
4
我们可以看到,结构体的零值是根据其字段类型的默认值来设置的。改变p2的值并不会影响已存储在数组中的结构体。

结构体指针的使用
指针是Go中强大的工具,可以避免复制大量数据。我们来看一个与结构体指针相关的例子pointerStruct.go。

首先,定义结构体:

package main
import (
"fmt"
)

type myStructure struct {
Name string
Surname string
Height int32
}
1
2
3
4
5
6
7
8
9
10
接下来,通过函数创建并返回结构体指针:

func createStruct(n, s string, h int32) *myStructure {
if h > 300 {
h = 0 // 校验身高是否合法
}
return &myStructure{n, s, h}
}
1
2
3
4
5
6
这个函数通过返回结构体的指针,避免了结构体的大量复制。也可以直接返回结构体:

func retStructure(n, s string, h int32) myStructure {
if h > 300 {
h = 0
}
return myStructure{n, s, h}
}
1
2
3
4
5
6
通过这两种方式创建的结构体,在使用上有一些差异。以下是测试代码:

func main() {
s1 := createStruct("李雷", "王花", 180)
s2 := retStructure("李雷", "王花", 180)

fmt.Println((*s1).Name)  // 输出结构体指针指向的Name
fmt.Println(s2.Name)     // 直接输出结构体的Name
fmt.Println(s1)          // 打印结构体指针
fmt.Println(s2)          // 打印结构体

}
1
2
3
4
5
6
7
8
9
运行结果如下:

李雷
李雷
&{李雷 王花 180}
{李雷 王花 180}
1
2
3
4
使用new关键字
Go支持使用new关键字来分配内存,并返回对象的内存地址。例如:

pS := new(aStructure)
1
通过new创建的结构体,所有字段的值都被初始化为零值。需要注意的是,new仅返回对象的指针,而make则不仅分配内存,还会对切片、映射和通道进行初始化。

元组与多返回值
虽然Go语言不直接支持元组类型,但函数可以返回多个值,具有类似元组的效果。来看一个返回三个值的函数:

package main
import (
"fmt"
)

func retThree(x int) (int, int, int) {
return 2 x, x x, -x
}

func main() {
fmt.Println(retThree(10)) // 输出三个返回值
n1, n2, n3 := retThree(20) // 接收返回值
fmt.Println(n1, n2, n3)

n1, n2 = n2, n1  // 交换值
fmt.Println(n1, n2, n3)

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
运行结果:

20 100 -10
40 400 -20
400 40 -20
1
2
3
元组的这种用法非常实用,例如用于交换值,或忽略某些返回值。

结论
通过结构体和元组,Go提供了强大的复合类型支持,让我们能够更好地组织和操作复杂的数据。在实际编程中,充分利用这些特性能够提高代码的可读性和效率。

文章知识点与官方知识档案匹配,可进一步学习相关知识
Go技能树九阴真经结构体4923 人正在系统学习中

相关文章
|
11天前
|
Go 索引
go语言中的循环语句
【11月更文挑战第4天】
20 2
|
3天前
|
安全 Go 数据处理
Go语言中的并发编程:掌握goroutine和channel的艺术####
本文深入探讨了Go语言在并发编程领域的核心概念——goroutine与channel。不同于传统的单线程执行模式,Go通过轻量级的goroutine实现了高效的并发处理,而channel作为goroutines之间通信的桥梁,确保了数据传递的安全性与高效性。文章首先简述了goroutine的基本特性及其创建方法,随后详细解析了channel的类型、操作以及它们如何协同工作以构建健壮的并发应用。此外,还介绍了select语句在多路复用中的应用,以及如何利用WaitGroup等待一组goroutine完成。最后,通过一个实际案例展示了如何在Go中设计并实现一个简单的并发程序,旨在帮助读者理解并掌
|
2天前
|
Go 索引
go语言按字符(Rune)遍历
go语言按字符(Rune)遍历
12 3
|
5天前
|
Go API 数据库
Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
本文介绍了 Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
25 4
|
5天前
|
缓存 监控 前端开发
在 Go 语言中实现 WebSocket 实时通信的应用,包括 WebSocket 的简介、Go 语言的优势、基本实现步骤、应用案例、注意事项及性能优化策略,旨在帮助开发者构建高效稳定的实时通信系统
本文深入探讨了在 Go 语言中实现 WebSocket 实时通信的应用,包括 WebSocket 的简介、Go 语言的优势、基本实现步骤、应用案例、注意事项及性能优化策略,旨在帮助开发者构建高效稳定的实时通信系统。
35 1
|
9天前
|
Go
go语言中的continue 语句
go语言中的continue 语句
21 3
|
9天前
|
安全 Go 调度
探索Go语言的并发模型:goroutine与channel
在这个快节奏的技术世界中,Go语言以其简洁的并发模型脱颖而出。本文将带你深入了解Go语言的goroutine和channel,这两个核心特性如何协同工作,以实现高效、简洁的并发编程。
|
11天前
|
Go
go语言中的 跳转语句
【11月更文挑战第4天】
20 4
|
10天前
|
JSON 安全 Go
Go语言中使用JWT鉴权、Token刷新完整示例,拿去直接用!
本文介绍了如何在 Go 语言中使用 Gin 框架实现 JWT 用户认证和安全保护。JWT(JSON Web Token)是一种轻量、高效的认证与授权解决方案,特别适合微服务架构。文章详细讲解了 JWT 的基本概念、结构以及如何在 Gin 中生成、解析和刷新 JWT。通过示例代码,展示了如何在实际项目中应用 JWT,确保用户身份验证和数据安全。完整代码可在 GitHub 仓库中查看。
49 1
|
4天前
|
存储 Go PHP
Go语言中的加解密利器:go-crypto库全解析
在软件开发中,数据安全和隐私保护至关重要。`go-crypto` 是一个专为 Golang 设计的加密解密工具库,支持 AES 和 RSA 等加密算法,帮助开发者轻松实现数据的加密和解密,保障数据传输和存储的安全性。本文将详细介绍 `go-crypto` 的安装、特性及应用实例。
14 0
下一篇
无影云桌面