首页 > 其他分享 >Go每日一库之173:Pie (高性能、类型安全的slice操作库)

Go每日一库之173:Pie (高性能、类型安全的slice操作库)

时间:2023-09-29 21:22:45浏览次数:37  
标签:slice 函数 元素 Pie pie 切片 一库 类型 name

在Go语言中,对slice和map是我们最常用的数据结构。比如,计算两个切片的交集、差集;判断切片中的元素是否都满足某个条件的等。我推荐大家使用这个包:[elliotchance/pie](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"
}

go1.17及以下版本需要使用pie/v1包。因为在1.17之前go还不支持泛型,所以函数只能针对特定类型的切片。在该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时内存申请的次数;使用切片截取的形式,避免内存再次分配。

标签:slice,函数,元素,Pie,pie,切片,一库,类型,name
From: https://www.cnblogs.com/arena/p/17737364.html

相关文章

  • Go每日一库之172:go-prompt
    简介受python提示工具包的启发,在Go中构建强大的交互式提示一、代码示例packagemainimport( "fmt" "github.com/c-bata/go-prompt")funccompleter(dprompt.Document)[]prompt.Suggest{ s:=[]prompt.Suggest{ {Text:"users",Description:"Store......
  • Go每日一库之133:lo(基于泛型的 Golang lodash 库)
    近日,Go核心开发团队终于宣布了Go1.18正式版本的发布!这是一个大家期待很久的版本!Go1.18包含大量新功能:模糊测试、性能改进、工作区等,以及Go语言开源以来最大的一次语法特性变更——支持泛型!支持泛型后,我们便不再需要写如下冗余的代码:现在只需要简单的一行即可:funcMi......
  • Go每日一库之132:wasm与tinygo
    WASM的概念,这几年还是挺火的,新的语言,比如Rust、Go、Swift等,都对WASM提供支持。相比之下,Go语言的简单性,使得对WASM的支持,使用起来也较简单。本文是目前公开资料中为数不多较完整的教程,希望能对你有帮助。WASM是什么标题说:“Golang中的Wasm太棒了。”,但请用几句话来说......
  • Go每日一库之131:caddy(轻量web服务器)
    一直以来,我都是使用Nginx作为Web服务器,但是配置可以说是非常麻烦了。每次我要新开一个域名,都要先使用acme.sh签发SSL证书,然后再写配置,大概要花上5分钟的时间。曾经想过写个脚本自动完成这些工作,但是苦于对Linux的了解不多,也就作罢了。最近看到了Caddy,一个用Go写的......
  • Go每日一库之130:go-humanize(人性化显示)
    go-humanize是一个「人性化」的Go语言库,人性化的意思不是形容这个Go语言库,而是这个Go语言库实现的功能,它可以把数字、时间、容量等转换为我们人类容易理解的词语,比如硬盘的容量是82854982bytes,我们可不太好理解,但是如果说容量是83M,那就好理解了,go-humanize干的就是这个事情。......
  • Go每日一库之129:promu(Prometheus构建发布工具)
    众所周知,Go语言中打包命令是gobuild。在项目中,你可以单独使用gobuild命令对项目进行编译打包,也可以根据自己的需要,在该命令后加各种参数。prometheus官方为了统一项目(包括prometheus、alertmanager和各种官方的exporter)的编译和打包,开发了promu工具。官方对promu工具......
  • Go每日一库之128:podinfo(k8s微服务模板)
    项目介绍官方Github:PodinfoPodinfo是一个用Go制作的小型web应用程序,它展示了在Kubernetes中运行微服务的最佳实践。它已实现的技术指标(截选自官方README.md):里面每一项技术指标的实现方式,其实都可以拿出来单独讲好久,相关理论也有好多。这里我只是讲针对这个项......
  • Go每日一库之145:MinIO(高性能对象存储)
    1.MinIO简介MinIO是一个基于Go实现的高性能、兼容S3协议的对象存储。它采用GNUAGPLv3开源协议,项目地址是https://github.com/minio/minio,官网是https://min.io。它适合存储海量的非结构化的数据,例如说图片、音频、视频等常见文件,备份数据、容器、虚拟机镜像等等,小......
  • Go每日一库之146:bbs-go(bbs框架)
    概要bbs-go是一款基于Go语言研发的开源、前后端分离、精美小巧、跨平台的社区系统。初期该项目仅用过学习和交流,开源之后越来越多的小伙伴儿开始喜欢和关注他,这也是我长期升级和维护的动力。bbs-go为前后端分离设计,后端接口服务使用简洁的Go语言进行开发,前端页面使用Vue.js进......
  • Go每日一库之144:go-obs-websocket(OBS连接器)
    推荐理由互联网的兴起带动了直播行业的火热,除了少数直播网站有自己的推流工具之外,OBS是主流的推流工具,广泛应用在直转播技术之上。简介go-obs-websocket是一个与OBS进行websocket通信的连接库,具备调用大部分OBS功能的接口,在互动直播和智能转播技术上广泛应用。快速开始安装g......