当前位置: 首页 > 科技观察

Go提案:添加通用版本的Slices和Maps新包

时间:2023-03-12 11:22:57 科技观察

转载本文请联系脑筋急转弯公众号。大家好,我是炸鱼。按照Go语言发布周期的2、8原则,现在是2021年8月。Go1.17即将发布,而在写这篇文章的时候,现在已经到了rc2:这意味着它离Go1.18发布的泛型的官方支持又近了一点,社区中的声音更多讨论与泛型相关的外围功能。今天要讨论的通用版本功能支持也是如此,包括支持三种通用类型:map(#47330)、slice(#45955)和container/set(#47331)。我们主要展开maps和slice,其他类似,理解核心思想即可。maps该提案建议定义一个新的包maps,它将提供可与任何类型的地图一起使用的功能:以下描述重点描述所提供的API:packagemapsfuncKeys[Kcomparable,Vany](mmap[K]V)[]KfuncValues[Kcomparable,Vany](mmap[K]V)[]VfuncEqual[K,Vcomparable](m1,m2map[K]V)boolfuncEqualFunc[Kcomparable,V1,V2any](m1map[K]V1,m2map[K]V2,cmpfunc(V1,V2)bool)boolfuncClear[Kcomparable,Vany](mmap[K]V)funcClone[Kcomparable,Vany](mmap[K]V)map[K]VfuncAdd[Kcomparable,Vany](dst,srcmap[K]V)funcFilter[Kcomparable,Vany](mmap[K]V,keepfunc(K,V)bool)Keys:返回map的键值。密钥将处于不确定的顺序。值:返回地图值。这些值将以不确定的顺序出现。相等:匹配两个映射是否包含相同的键/值对。EqualFunc:EqualFunc类似于Equal,但使用cmp进行数值比较。清除:清除地图中的所有条目,使其为空。Clone:返回地图的副本,是浅克隆。使用普通赋值设置新键和值。添加:将src中的所有键/值对添加到dst。当src中的某个键已经存在于dst中时,dst中的值将被与src中的键关联的值覆盖。过滤器:过滤器从映射中删除任何keep返回false的键/值对。slices该提案建议定义一个新的包slice,它将提供可与任何类型的切片一起使用的函数:以下描述重点描述所提供的API:packageslicesimport"constraint"funcEqual[Tcomparable](s1,s2[]T)boolfuncEqualFunc[T1,T2any](s1[]T1,s2[]T2,eqfunc(T1,T2)bool)boolfuncCompare[Tconstraints.Ordered](s1,s2[]T)intfuncCompareFunc[Tany](s1,s2[]T,cmpfunc(T,T)int)intfuncIndex[Tcomparable](s[]T,vT)intfuncIndexFunc[Tany](s[]T,ffunc(T)bool)intfuncContains[Tcomparable](s[]T,vT)boolfuncInsert[Sconstraints.Slice[T],Tany](sS,iint,v...T)SfuncDelete[Sconstraints.Slice[T],Tany](sS,i,jint)SfuncClone[Sconstraints.Slice[T],Tany](sS)SEqual:检查两个切片是否相等,通过长度和元素值进行比较。EqualFunc:检查两个切片是否相等,将它们与传入的匹配函数进行比较。Compare/CompareFunc:比较两个切片s1和s2的元素。CompareFunc类似于Compare,对每对元素使用传入的比较函数。Index:Index返回v在slices中第一次出现的索引,如果不存在则返回-1。IndexFunc返回第一个满足f(c)的元素在s中的索引,如果不存在则返回-1。包含:检查值v是否存在于切片s中。插入、删除、克隆的API比较常用,这里就不展开了。通用类型的切片有一些特殊的API:.Slice[T],Tany](sS,nint)SfuncClip[Sconstraints.Slice[T],Tany](sS)SCompact/CompactFunc:Compact用单个副本替换连续运行的相等元素。这类似于Unix中的uniq命令。将直接修改slice的内容,而不重新创建一个。CompactFunc类似于Compact方法,但使用比较函数进行匹配。Grow:如有必要,Grow将增加切片的容量以保证为另外n个元素提供空间。在Grow(n)之后,至少可以将n个元素添加到切片中而无需重新分配。如果n为负数或太大而无法分配内存,Grow将panic。Clip:从切片中移除未使用的容量,返回s[:len(s):len(s)]。总结如果这些提议被接受,这些新包将包含在实现泛型后的第一个Go版本中(我们目前预计是Go1.18)。从issue的讨论来看,对通用类型的新封装支持很可能会实现,主要争议在于实现细节,比如:性能、命名、规范等,实现后值得期待,这是生产力的另一种优化!