带你入门 Go 语言中的泛型编程

简介: 带你入门 Go 语言中的泛型编程

Go 语言自从 1.18 版本开始引入了泛型编程的概念。

泛型编程允许我们编写更加灵活和可重用的代码。但如果你是编程小白,可能对泛型这个词感到陌生。不用担心,本文将用最简单的语言和例子,帮助你理解 Go 语言中的泛型编程。

什么是泛型

泛型,顾名思义,就是指的“泛化的类型”。在编程中,泛型让我们可以编写代码时不指定具体的数据类型,而是在实际使用时再确定数据类型。

Go 语言中的泛型

在 Go 语言中,泛型主要是通过类型参数(Type Parameters)来实现的。类型参数可以看作是一个占位符,它在定义时不指定具体类型,在使用时再由用户指定。

示例1:泛型函数

假设我们要写一个函数,这个函数可以比较两个值的大小并返回较大的值。

通常情况下,我们需要为不同的类型写多个函数,比如比较整数、比较浮点数等等。但有了泛型,我们只需要写一个函数:

package main
import "fmt"
// 这里的 T 是一个类型参数,它是一个占位符,具体的类型在调用函数时确定。
func Max[T comparable](a, b T) T {
 if a > b {
  return a
 }
 return b
}
func main() {
 // 使用泛型函数比较整数
 fmt.Println(Max(3, 5)) // 输出:5
 // 使用泛型函数比较浮点数
 fmt.Println(Max(3.14, 1.59)) // 输出:3.14
 // 使用泛型函数比较字符串
 fmt.Println(Max("apple", "banana")) // 输出:banana
}

在上述代码中,Max 函数定义了一个类型参数 T,并且 T 需要满足 comparable 的约束,意味着 T 的类型必须是可比较的(比如整数、浮点数、字符串等)。这样我们就可以使用同一个函数来比较不同类型的值了。

示例二:泛型类型

例如,我们可以定义一个可以存储任意类型元素的自定义切片:

package main
import "fmt"
// 定义一个泛型切片类型
type MySlice[T any] []T
// 为 MySlice 类型添加一个方法,用于添加元素
func (s *MySlice[T]) Add(elem T) {
 *s = append(*s, elem)
}
func main() {
 // 创建一个存储整数的 MySlice
 intSlice := MySlice[int]{}
 intSlice.Add(1)
 intSlice.Add(2)
 fmt.Println(intSlice) // 输出:[1 2]
 // 创建一个存储字符串的 MySlice
 stringSlice := MySlice[string]{}
 stringSlice.Add("hello")
 stringSlice.Add("world")
 fmt.Println(stringSlice) // 输出:[hello world]
}

在这个例子中,我们定义了一个名为 MySlice 的泛型类型,它接受一个类型参数 T。然后我们为 MySlice 定义了一个 Add 方法,用于向切片中添加元素。可以看到,无论是存储整数还是字符串,我们都可以使用同一个 MySlice 类型。

小结

泛型编程是一个强大的工具,它可以让我们写出更加通用和灵活的代码。通过本文的介绍,你应该对Go语言中的泛型有了初步的了解。

目录
相关文章
|
9天前
|
程序员 Go PHP
为什么大部分的 PHP 程序员转不了 Go 语言?
【9月更文挑战第8天】大部分 PHP 程序员难以转向 Go 语言,主要因为:一、编程习惯与思维方式差异,如语法风格和编程范式;二、学习成本高,需掌握新知识体系且面临项目压力;三、职业发展考量,现有技能价值及市场需求不确定性。学习新语言虽有挑战,但对拓宽职业道路至关重要。
38 10
|
7天前
|
Go API 开发者
深入探讨:使用Go语言构建高性能RESTful API服务
在本文中,我们将探索Go语言在构建高效、可靠的RESTful API服务中的独特优势。通过实际案例分析,我们将展示Go如何通过其并发模型、简洁的语法和内置的http包,成为现代后端服务开发的有力工具。
|
9天前
|
算法 程序员 Go
PHP 程序员学会了 Go 语言就能唬住面试官吗?
【9月更文挑战第8天】学会Go语言可提升PHP程序员的面试印象,但不足以 solely “唬住” 面试官。学习新语言能展现学习能力、拓宽技术视野,并增加就业机会。然而,实际项目经验、深入理解语言特性和综合能力更为关键。全面展示这些方面才能真正提升面试成功率。
31 10
|
8天前
|
编译器 Go
go语言学习记录(关于一些奇怪的疑问)有别于其他编程语言
本文探讨了Go语言中的常量概念,特别是特殊常量iota的使用方法及其自动递增特性。同时,文中还提到了在声明常量时,后续常量可沿用前一个值的特点,以及在遍历map时可能遇到的非顺序打印问题。
|
6天前
|
存储 监控 数据可视化
Go 语言打造公司监控电脑的思路
在现代企业管理中,监控公司电脑系统对保障信息安全和提升工作效率至关重要。Go 语言凭借其高效性和简洁性,成为构建监控系统的理想选择。本文介绍了使用 Go 语言监控系统资源(如 CPU、内存)和网络活动的方法,并探讨了整合监控数据、设置告警机制及构建可视化界面的策略,以满足企业需求。
23 1
|
4月前
|
开发框架 安全 中间件
Go语言开发小技巧&易错点100例(十二)
Go语言开发小技巧&易错点100例(十二)
58 1
|
1月前
|
JSON 中间件 Go
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
本文详细介绍了如何在Go项目中集成并配置Zap日志库。首先通过`go get -u go.uber.org/zap`命令安装Zap,接着展示了`Logger`与`Sugared Logger`两种日志记录器的基本用法。随后深入探讨了Zap的高级配置,包括如何将日志输出至文件、调整时间格式、记录调用者信息以及日志分割等。最后,文章演示了如何在gin框架中集成Zap,通过自定义中间件实现了日志记录和异常恢复功能。通过这些步骤,读者可以掌握Zap在实际项目中的应用与定制方法
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
|
1月前
|
算法 NoSQL 中间件
go语言后端开发学习(六) ——基于雪花算法生成用户ID
本文介绍了分布式ID生成中的Snowflake(雪花)算法。为解决用户ID安全性与唯一性问题,Snowflake算法生成的ID具备全局唯一性、递增性、高可用性和高性能性等特点。64位ID由符号位(固定为0)、41位时间戳、10位标识位(含数据中心与机器ID)及12位序列号组成。面对ID重复风险,可通过预分配、动态或统一分配标识位解决。Go语言实现示例展示了如何使用第三方包`sonyflake`生成ID,确保不同节点产生的ID始终唯一。
go语言后端开发学习(六) ——基于雪花算法生成用户ID
|
1月前
|
JSON 缓存 监控
go语言后端开发学习(五)——如何在项目中使用Viper来配置环境
Viper 是一个强大的 Go 语言配置管理库,适用于各类应用,包括 Twelve-Factor Apps。相比仅支持 `.ini` 格式的 `go-ini`,Viper 支持更多配置格式如 JSON、TOML、YAML
go语言后端开发学习(五)——如何在项目中使用Viper来配置环境
|
3月前
|
中间件 Go
go语言后端开发学习(三)——基于validator包实现接口校验
go语言后端开发学习(三)——基于validator包实现接口校验