「Go 工具箱」Pie :一个高性能、类型安全的 slice 操作库
大家好,我是渔夫子。本号新推出「Go 工具箱」系列,意在给大家分享使用 go 语言编写的、实用的、好玩的工具。同时了解其底层的实现原理,以便更深入地了解 Go 语言。
在 Go 语言中,对 slice 和 map 是我们最常用的数据结构。比如,计算两个切片的交集、差集;判断切片中的元素是否都满足某个条件的等。我推荐大家使用这个包:elliotchance/pie
。以下是该包的基本情况:
star:1.3k
作者:Elliot Chance
项目地址:https://github.com/elliotchance/pie
功能简介:该包封装了对切片和 map 的常用操作,能满足工作中的大部分需求。比如计算切片的交集、差集;对切片中元素按条件过滤的 Filter 函数;对切片中元素进行数据转换的 Each、Map 函数等。同时具有高性能、类型安全的特点。实现中对各函数的参数都做了类型的限制。比如 Average 函数就只能对整型和浮点型参数有效。
使用 pie 包的要求:
pie v2 版本需要 Go 1.18+。Go1.17 及以下版本需要使用 v1 版本。
pie 包的目标:
类型安全:无论是在 v1 版本还是 v2 版本的泛型中,都对类型做了限制,所以不会遇到运行时类型错误。
高性能:该库需要跟原生的 Go 实现一样快,否则该库封装就没有意义。
Nil 安全:该库的所有函数都能接收 nil 参数,并将其视为空切片,而不会引起 panic。
对原切片无副作用:所有的函数对传入的切片参数都不会做修改。
使用示例
go 版本在 1.18 及以上,会使用 pie/v2 包,该包使用的是泛型。
go 版本在 1.17 及以下,go 还不支持泛型。那么就需要使用 pie/v1 的版本。在该版本中,实际上在 pie 中定义了一组类型切片。比如,代表 string 切片的 pie.Strings 类型。代表 float64 切片的 pie.Float64s 类型。那么该版本在使用时需要先定义切片的类型。如下:
pie 包支持的功能:
切片中的元素是否全部或任意一个满足指定的条件。
All 函数:判断切片中的元素是否都满足指定的条件。
Any 函数:判断切片中的元素只要有 1 个满足指定条件即可。
对切片元素进行排序功能。
AreSorted 函数:判断切片是否是有序的
Sort 函数:对切片元素进行排序。
SortStableUsing 函数:使用指定的条件对切片进行排序,并且具有稳定性。
SortUsing 函数
对切片中的元素去重。
判断切片中的元素是否不重复的 AreUnique 函数、去重函数 Unique
对切片进行前、后截取。
Bottom 函数:取切片后 n 个元素
Top 函数:取切片前 n 个元素
DropTop 函数:丢掉切片的前 n 个元素,并返回剩余的元素切片
两个或多个切片之间的集合运算
Diff 函数:计算两个切片中的差集
Intersect 函数:计算两个或多个切片的交集
切片元素进行算数运算功能(只针对 Integer 和 float 类型的切片有效)。
Max 函数:返回切片中的最大元素
Min 函数:返回切片中的最小元素
Product 函数:对切片所有元素进行乘积运算
Sum 函数:对切片中所有元素进行求和运算
Average 函数:求所有元素的平均值
对切片中的元素进行数据转换功能:Each、Map、Filter、Flat、Reducer
针对 map 的操作:
Keys 函数:获取 map 的所有键
Values 函数:获取 map 的所有值
更多、更详细的功能请参考 pie 包的源码。
总结
pie 包几乎把 slice 经常用到的功能都做了封装,可谓是给开发者节省了大量时间。同时,v2 包利用了泛型中的类型限制,保证了类型的安全。在性能方面,该包采用了很多策略:在已知切片长度的情况下尽可能给 slice 分配固定长度的内存,减少在使用 append 时内存申请的次数;使用切片截取的形式,避免内存再次分配。
特别推荐:一个专注 go 项目实战、项目中踩坑经验及避坑指南、各种好玩的 go 工具的公众号,「Go 学堂」,专注实用性,非常值得大家关注。点击下方公众号卡片,直接关注。关注送《100 个 go 常见的错误》pdf 文档。
版权声明: 本文为 InfoQ 作者【Go学堂】的原创文章。
原文链接:【http://xie.infoq.cn/article/3bf0f3c0557a1b1e6e5c8e274】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论