go1.23 新的正式特性 range ofer func 看了下没怎么看懂。。。

for range 返回一个函数,函数里面还是 for range 或者就 for 循环:

```go
func Backward[E any](s []E) func(func(int, E) bool) {
    return func(yield func(int, E) bool) {
        for i := len(s) - 1; i >= 0; i-- {
            if !yield(i, s) {
                return
            }
        }
        return
    }
}

func main() {
    sl := []string{"hello", "world", "golang"}
    for i, s := range Backward(sl) {
        fmt.Printf("%d : %s\n", i, s)
    }
}
```

`Backward`这个函数这形式看起来还真有点复杂,不好理解。。。。可能例子不是相应场景下需要的,看半天没理解。
感觉一般都用不上。
举报· 918 次点击
登录 注册 站外分享
64 条回复  
lveye 小成 2024-8-20 16:57:46
官方的例子是这个 https://go.dev/wiki/RangefuncExperiment ,一样的东西。看着还挺不错,满足这 2 个一级函数就可以进行 for range 。

type Seq[V any] func(yield func(V) bool)

type Seq2[K, V any] func(yield func(K, V) bool)
allenby 小成 2024-8-20 12:42:51
看着像是在循环的时候返回本身和索引
june4 小成 2024-8-20 09:24:35
@xz410236056 其它语言也都有生成器,比如 js 也有生成器协议,但人家同时还有 yield 语法糖可以掩盖底下丑陋的协议,用起来象 return 一样简单可读,没人会直接用原始协议的格式来写生成器,太丑了。
yumenaka 小成 2024-8-20 09:08:22
作为一个调库的低水平用户,range ofer func 让我少写了不少模板代码。
因为调库的地方,总是比写库的地方多,我的项目的阅读难度其实是下降了。

复杂性从来都不会消失,只是被封装。
抱怨第三方库会因此变难的用户,技能应该比我熟练,经常阅读第三方库。但做的工作,又没有涉及更底层的部分吧。

至于语法与格式……
用 go 的人,不是从一开始就接受了 go fmt 吗?
mark2025 小成 2024-8-19 23:44:17
@DOLLOR ts 看起来似乎顺眼些~
collery 小成 2024-8-19 23:36:58
不好意思,方法签名数括号没数过来~~~
低智 javaer
DOLLOR 小成 2024-8-19 23:26:17
把 OP 的 go 翻译成 TS ,大概是这样子的

const Backward = <E>(s: E[]): (myYield: (i: number, e: E) => boolean) => void => {
⬜return (myYield: (i: number, e: E) => boolean) => {
⬜⬜for (let i = s.length - 1; i >= 0; i -= 1) {
⬜⬜⬜if (!(myYield(i, s))) {
⬜⬜⬜⬜return
⬜⬜⬜}
⬜⬜}
⬜⬜return
⬜}
}

const main = () => {
⬜const sl = ["hello", "world", "golang"]
⬜forRange(Backward(sl), (i, s) => {
⬜⬜console.log(`${i} : ${s}`)
⬜⬜return true
⬜})
}

// 模拟 for range 的行为
const forRange = <E>(
⬜iter: (myYield: (i: number, e: E) => boolean) => void,
⬜body: (i: number, s: E) => boolean
) => {
⬜iter(body)
}

main()


也就是说,迭代器并没有增加任何新的语法,就是单纯满足签名为 func(func(int, E) bool)的函数。
你说它繁杂、丑陋嘛,确实,要写大量的模板代码。
但你说它大道至简嘛,确实,没有增加任何新的语法。😂
jiangzm 小成 2024-8-19 22:32:38
语法过于丑漏
james122333 初学 2024-8-19 21:54:35
我也觉得这过于複杂
FYFX 小成 2024-8-19 21:03:18
https://go.dev/wiki/RangefuncExperiment ,OP 应该在一开始就把官方给的例子贴全了
说起来要是我理解的没问题
for i,s := range Backward(sl){...} 这里的 i,s 不是从 Backward 函数返回的,更像是给回调函数声明用的?然后编译器再往回调函数里面补个 return true?
返回顶部