写点什么

「Go 工具箱」Pie :一个高性能、类型安全的 slice 操作库

作者:Go学堂
  • 2023-03-07
    北京
  • 本文字数:1813 字

    阅读完需:约 6 分钟

「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 包,该包使用的是泛型。


package main
import ( "fmt" "strings"
"github.com/elliotchance/pie/v2")
func main() {
name := pie.Of([]string{"Bob", "Sally", "John", "Jane"}). FilterNot(func(name string) bool { return strings.HasPrefix(name, "J") }). Map(strings.ToUpper). Last()
fmt.Println(name) // "SALLY"}
复制代码


go 版本在 1.17 及以下,go 还不支持泛型。那么就需要使用 pie/v1 的版本。在该版本中,实际上在 pie 中定义了一组类型切片。比如,代表 string 切片的 pie.Strings 类型。代表 float64 切片的 pie.Float64s 类型。那么该版本在使用时需要先定义切片的类型。如下:


package main
import ( "fmt" "strings"
"github.com/elliotchance/pie/pie")
func main() { var names pie.Strings //看pie的源码Strings的底层类型是[]string names = []string{"Bob", "Sally", "John", "Jane"}
name := names.FilterNot(func(name string) bool { return strings.HasPrefix(name, "J") }). Map(strings.ToUpper). Last()
fmt.Println(name) // "SALLY"}
复制代码

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 文档。

发布于: 2023-03-07阅读数: 38
用户头像

Go学堂

关注

微信公众号:Go学堂 2019-08-06 加入

专注Go编程知识、案例、常见错误及原理分析。意在通过阅读更多优秀的代码,提高编程技能。同名公众号「Go学堂」期待你的关注

评论

发布
暂无评论
「Go工具箱」Pie :一个高性能、类型安全的slice操作库_golang_Go学堂_InfoQ写作社区