Go语言泛型-泛型约束与实践(go1.7泛型)
bigegpt 2025-07-10 13:19 12 浏览
来源:械说
在Go语言中,Go泛型-泛型约束与实践部分主要探讨如何定义和使用泛型约束(Constraints),以及如何在实际开发中利用泛型进行更灵活的编程。以下是详细内容:
一、什么是泛型约束?
**泛型约束(Constraints)**用于限制一个类型参数的可能类型。在 Go 泛型中,可以通过接口类型来限制类型参数的范围。泛型约束提供了更高的类型安全性,保证了类型操作的合理性。
二、基本的泛型约束语法
Go 的泛型约束主要通过 interface 来实现。可以通过将接口作为类型约束,指定泛型函数或类型的类型参数应满足哪些条件。
1. 无约束(any 或 interface{})
如果没有对类型进行限制,类型参数可以是任意类型,any 是 interface{} 的别名。
funcPrint[Tany](value T) { fmt.Println(value)}
这个函数可以接受任意类型的值作为参数。
2. 有限制的约束
泛型约束可以让我们限制类型参数必须满足特定接口,或者属于某些基本类型。
typeNumericinterface{int|int32|int64|float32|float64}funcAdd[TNumeric](a, b T) T {returna + b}
在上面的例子中,Numeric 类型约束要求 T 必须是 int、int32、int64、float32 或 float64 中的任意一种类型。
三、Go中的内建类型约束
Go 1.18 引入了
golang.org/x/exp/constraints 包,提供了一些预定义的类型约束,可以直接使用这些约束来避免自己手动定义。
1. constraints.Ordered
用于限制支持排序的类型,例如数值类型和字符串。
import"golang.org/x/exp/constraints"funcMax[Tconstraints.Ordered](a, b T) T {ifa > b {returna }returnb}2. constraints.Comparable
用于限制支持比较的类型,包含了能进行 == 和 != 比较的类型。
funcContains[Tconstraints.Comparable](arr []T, value T)bool{for_, v :=rangearr {ifv == value {returntrue} }returnfalse}3. constraints.Integer
用于限制整型数值。
funcMultiply[Tconstraints.Integer](a, b T) T {returna * b}4. constraints.Float
用于限制浮动数值。
funcDivide[Tconstraints.Float](a, b T) T {returna / b}
四、使用自定义泛型约束
除了使用 Go 标准库提供的泛型约束,我们还可以根据实际需求定义自定义的类型约束。
1. 多个类型约束的组合
可以通过接口类型组合多个约束。组合多个约束可以让你指定更具体的约束条件。
typeOrderedNumericinterface{ constraints.Ordered constraints.Integer | constraints.Float}funcCalculate[TOrderedNumeric](a, b T) T {returna + b}
这里 OrderedNumeric 类型约束要求 T 必须是一个可排序的数值类型(整型或浮点型)。
2. 约束接口与类型集合
自定义泛型约束接口时,可以结合类型集合的方式进行限制。以下是一个示例:
typeStringerinterface{ Stringstring}typePrinter[T Stringer]interface{ Print(value T)}
在此示例中,我们创建了一个约束类型 Stringer,它要求类型 T 必须实现 String 方法。
五、实践示例1. 泛型容器类:栈(Stack)packagemainimport"fmt"typeStack[T any]struct{ elements T}func(s *Stack[T]) Push(value T) { s.elements =append(s.elements, value)}func(s *Stack[T]) Pop T { lastIndex :=len(s.elements) -1value := s.elements[lastIndex] s.elements = s.elements[:lastIndex]returnvalue}func(s *Stack[T]) Top T {returns.elements[len(s.elements)-1]}funcmain { s := Stack[int]{} s.Push(1) s.Push(2) fmt.Println(s.Pop)// Output: 2}
在上面的示例中,Stack 类型是一个泛型类型,支持任意类型的数据操作。无论是整数、字符串还是自定义类型,都可以通过栈结构进行管理。
2. 泛型排序函数:通用排序packagemainimport"fmt"typeOrderedinterface{int|float64|string}funcSort[TOrdered](values []T) T {fori :=0; i len(values)-1; i++ {forj :=0; j len(values)-i-1; j++ {ifvalues[j] > values[j+1] { values[j], values[j+1] = values[j+1], values[j] } } }returnvalues}funcmain { arr := int{5,3,4,1,2} sorted := Sort(arr) fmt.Println(sorted)// Output: [1 2 3 4 5]}
这里我们创建了一个 Sort 函数,它支持 int、float64 和 string 类型的排序。通过泛型约束 Ordered,我们保证了只有这些可排序类型可以传入 Sort 函数。
六、泛型的应用场景1. 实现常见的数据结构和算法
泛型最常用于实现常见的数据结构,如链表、栈、队列等,以及一些常见的算法(如排序、查找、映射等)。
2. 构建通用库和工具
通过泛型,可以编写更加通用的库和工具,使得它们可以在多种数据类型上工作,提升代码复用性。
3. 函数式编程风格
通过使用泛型函数,例如 Map、Reduce 和 Filter 等,可以实现函数式编程的风格,使得代码更加简洁和高效。
七、总结
- o泛型约束使得 Go 泛型变得更加灵活和强大,支持了多种类型操作,同时保证了类型安全。
- o 使用 Go 标准库中的预定义约束或自定义约束,可以轻松限制类型参数的范围,确保代码的高效性与可维护性。
- o 通过泛型实现的通用算法和数据结构,能够减少重复代码,并提高代码复用性。
- 上一篇:golang总结(golang实战教程)
- 已经是最后一篇了
相关推荐
- Go语言泛型-泛型约束与实践(go1.7泛型)
-
来源:械说在Go语言中,Go泛型-泛型约束与实践部分主要探讨如何定义和使用泛型约束(Constraints),以及如何在实际开发中利用泛型进行更灵活的编程。以下是详细内容:一、什么是泛型约束?**泛型...
- golang总结(golang实战教程)
-
基础部分Go语言有哪些优势?1简单易学:语法简洁,减少了代码的冗余。高效并发:内置强大的goroutine和channel,使并发编程更加高效且易于管理。内存管理:拥有自动垃圾回收机制,减少内...
- Go 官宣:新版 Protobuf API(go pro版本)
-
原文作者:JoeTsai,DamienNeil和HerbieOng原文链接:https://blog.golang.org/a-new-go-api-for-protocol-buffer...
- Golang开发的一些注意事项(一)(golang入门项目)
-
1.channel关闭后读的问题当channel关闭之后再去读取它,虽然不会引发panic,但会直接得到零值,而且ok的值为false。packagemainimport"...
- golang 托盘菜单应用及打开系统默认浏览器
-
之前看到一个应用,用go语言编写,说是某某程序的windows图形化客户端,体验一下发现只是一个托盘,然后托盘菜单的控制面板功能直接打开本地浏览器访问程序启动的webserver网页完成gui相关功...
- golang标准库每日一库之 io/ioutil
-
一、核心函数概览函数作用描述替代方案(Go1.16+)ioutil.ReadFile(filename)一次性读取整个文件内容(返回[]byte)os.ReadFileioutil.WriteFi...
- 文件类型更改器——GoLang 中的 CLI 工具
-
我是如何为一项琐碎的工作任务创建一个简单的工具的,你也可以上周我开始玩GoLang,它是一种由Google制作的类C编译语言,非常轻量和快速,事实上它经常在Techempower的基准测...
- Go (Golang) 中的 Channels 简介(golang channel长度和容量)
-
这篇文章重点介绍Channels(通道)在Go中的工作方式,以及如何在代码中使用它们。在Go中,Channels是一种编程结构,它允许我们在代码的不同部分之间移动数据,通常来自不同的goro...
- Golang引入泛型:Go将Interface「」替换为“Any”
-
现在Go将拥有泛型:Go将Interface{}替换为“Any”,这是一个类型别名:typeany=interface{}这会引入了泛型作好准备,实际上,带有泛型的Go1.18Beta...
- 一文带你看懂Golang最新特性(golang2.0特性)
-
作者:腾讯PCG代码委员会经过十余年的迭代,Go语言逐渐成为云计算时代主流的编程语言。下到云计算基础设施,上到微服务,越来越多的流行产品使用Go语言编写。可见其影响力已经非常强大。一、Go语言发展历史...
- Go 每日一库之 java 转 go 遇到 Apollo?让 agollo 来平滑迁移
-
以下文章来源于GoOfficialBlog,作者GoOfficialBlogIntroductionagollo是Apollo的Golang客户端Apollo(阿波罗)是携程框架部门研...
- Golang使用grpc详解(golang gcc)
-
gRPC是Google开源的一种高性能、跨语言的远程过程调用(RPC)框架,它使用ProtocolBuffers作为序列化工具,支持多种编程语言,如C++,Java,Python,Go等。gR...
- Etcd服务注册与发现封装实现--golang
-
服务注册register.gopackageregisterimport("fmt""time"etcd3"github.com/cor...
- Golang:将日志以Json格式输出到Kafka
-
在上一篇文章中我实现了一个支持Debug、Info、Error等多个级别的日志库,并将日志写到了磁盘文件中,代码比较简单,适合练手。有兴趣的可以通过这个链接前往:https://github.com/...
- 如何从 PHP 过渡到 Golang?(php转golang)
-
我是PHP开发者,转Go两个月了吧,记录一下使用Golang怎么一步步开发新项目。本着有坑填坑,有错改错的宗旨,从零开始,开始学习。因为我司没有专门的Golang大牛,所以我也只能一步步自己去...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- libcrypto.so (74)
- linux安装minio (74)
- ubuntuunzip (67)
- vscode使用技巧 (83)
- secure-file-priv (67)
- vue阻止冒泡 (67)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)