最近 Go1.23 进入了冻结阶段,意味着不再添加新功能,而且已经加入的功能也不再会删除。
Go 1.23 正式引入了 iter 软件包,这是一个专门用于 Iterators 的新特性。
该软件包在 Go 1.22 中作为实验性功能,需要通过 GOEXPERIMENT=rangefunc 参数启用。
在 Go 1.23 中,开发者可以直接通过代码实现迭代。
在这之前循环将切片数据全部转换为大写时的写法:
func Convert[S any, D any](src []S, mapFn func(s S) D) []D { r := make([]D, 0, len(src)) for _, i := range src { r = append(r, mapFn(i)) } return r } func ToUpByString() { sl := []string{"hello", "world", "golang"} s0 := Convert(sl, func(v string) string { return strings.ToUpper(v) }) for _, v := range s0 { // do business } }
而在使用新的 Iter 迭代器之后:
func Backward(s []string) func(yield func(string) bool) { return func(yield func(string) bool) { for i := len(s) - 1; i >= 0; i-- { yield(strings.ToUpper(s[i])) } } } func ToUpperByIter() { sl := []string{"hello", "world", "golang"} for v := range Backward(sl) { // do business } }
可以发现明显的代码量减少了,同时更符合函数式编程的特性。
通过性能比较,ToUpperByIter 方法性能更高,因为它不需要重新分配新的切片。
➜ huizhou92 git:(master) ✗ go test -bench . -count=3 goos: darwin goarch: arm64 pkg: huizhou92 cpu: Apple M1 Pro BenchmarkToUpByString-10 8568332 128.7 ns/op BenchmarkToUpByString-10 9310351 128.6 ns/op BenchmarkToUpByString-10 9344986 128.5 ns/op BenchmarkToUpByIter-10 12440120 96.22 ns/op BenchmarkToUpByIter-10 12436645 96.25 ns/op BenchmarkToUpByIter-10 12371175 96.64 ns/op PASS ok huizhou92 8.162s
iter 软件包提供了两种迭代器类型:
具体函数声明如下:
// 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. type Seq[V any] 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. type Seq2[K, V any] func(yield func(K, V) bool)
iter 软件包的目标是提供一种统一和高效的迭代方法,并且已经在 map 包中添加了 All 和 Keys 等方法。
具体列表如下:
图片
图片
而社区对于 yield 和 iter 的引入有不同意见,有人认为它会引入复杂性和难以可理解的代码,而另一些则认为它能够帮助开发者简化代码并采用更多函数式编程。
个人觉得 Go 在新版本映入一些新特性是有必要的,这样才能保持社区的活跃,同时选择权也是交给开发者的。
类似的在 Java8 中引入的 lambda 表达式起初也是有很多人反馈难以阅读与调试,经过这么多年的普及以及 IDE 的支持,现在已经成为大多数开发者的标配了。
参考链接:
本文链接://www.dmpip.com//www.dmpip.com/showinfo-26-95916-0.htmlGo 1.23:拥抱iter包,简化你的迭代逻辑
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
上一篇: 电商系统开发所遇问题及C#实例解析
下一篇: C++多线程中的互斥锁