Go 1.23:拥抱iter包,简化你的迭代逻辑

类似的在 Java8 中引入的 lambda 表达式起初也是有很多人反馈难以阅读与调试,经过这么多年的普及以及 IDE 的支持,现在已经成为大多数开发者的标配了。
首页 新闻资讯 行业资讯 Go 1.23:拥抱iter包,简化你的迭代逻辑

最近 Go1.23 进入了冻结阶段,意味着不再添加新功能,而且已经加入的功能也不再会删除。

Go 1.23 正式引入了 iter 软件包,这是一个专门用于 Iterators 的新特性。

该软件包在 Go 1.22 中作为实验性功能,需要通过 GOEXPERIMENT=rangefunc 参数启用。

在 Go 1.23 中,开发者可以直接通过代码实现迭代。

在这之前循环将切片数据全部转换为大写时的写法:

funcConvert[Sany,Dany](src[]S,mapFn func(s S)D)[]D {  
     r :=make([]D,0,len(src))for_,i :=range src {  
        r=append(r,mapFn(i))}returnr  
 }  
   
 func ToUpByString(){  
     sl :=[]string{"hello","world","golang"}  
     s0 :=Convert(sl,func(v string)string {returnstrings.ToUpper(v)})for_,v :=range s0 {// do business}  
 }

而在使用新的 Iter 迭代器之后:

func Backward(s[]string)func(yield func(string)bool){returnfunc(yield func(string)bool){fori :=len(s)-1;i>=0;i-- {yield(strings.ToUpper(s[i]))}
   }
 }
 
 func ToUpperByIter(){
   sl :=[]string{"hello","world","golang"}forv :=range Backward(sl){// do business}
 }

可以发现明显的代码量减少了,同时更符合函数式编程的特性。

通过性能比较,ToUpperByIter 方法性能更高,因为它不需要重新分配新的切片。

➜  huizhou92 git:(master)✗ go test-bench.-count=3goos: darwin
 goarch: arm64
 pkg: huizhou92
 cpu: Apple M1 Pro
 BenchmarkToUpByString-108568332128.7ns/op
 BenchmarkToUpByString-109310351128.6ns/op
 BenchmarkToUpByString-109344986128.5ns/op
 BenchmarkToUpByIter-101244012096.22ns/op
 BenchmarkToUpByIter-101243664596.25ns/op
 BenchmarkToUpByIter-101237117596.64ns/op
 PASS
 ok      huizhou928.162s

iter 软件包提供了两种迭代器类型:

  • Seq 用于单个值的迭代

  • Seq2 用于键值对的迭代。

具体函数声明如下:

// Seq is an iterator over sequences of individual values.// When called as seq(yield), seq calls yield(v) for each value v in the sequence,// stopping early if yield returns false.typeSeq[Vany]func(yield func(V)bool)// Seq2 is an iterator over sequences of pairs of values, most commonly key-value pairs.// When called as seq(yield), seq calls yield(k, v) for each pair (k, v) in the sequence,// stopping early if yield returns false.typeSeq2[K,Vany]func(yield func(K,V)bool)

iter 软件包的目标是提供一种统一和高效的迭代方法,并且已经在 map 包中添加了 All 和 Keys 等方法。

具体列表如下:

图片图片

图片图片

而社区对于 yield 和 iter 的引入有不同意见,有人认为它会引入复杂性和难以可理解的代码,而另一些则认为它能够帮助开发者简化代码并采用更多函数式编程。

个人觉得  Go 在新版本映入一些新特性是有必要的,这样才能保持社区的活跃,同时选择权也是交给开发者的。

类似的在 Java8 中引入的 lambda 表达式起初也是有很多人反馈难以阅读与调试,经过这么多年的普及以及 IDE 的支持,现在已经成为大多数开发者的标配了。

参考链接:

  • https://tip.golang.org/doc/go1.23#iterators

  • https://levelup.gitconnected.com/go-1-23-new-iter-package-4ae649a0e910

  • https://pkg.go.dev/iter@master#hdr-Iterators

37    2024-06-24 08:10:34    Java8 表达式 IDE