go - 在 go 中轮询函数直到 ok != true 的惯用方式

标签 go

我有一个函数,它在轮询时返回值,但在某些时候将停止返回合理的值,如下所示。

有没有比每次检查 if !ok 更惯用的方式来轮询它。我在想类似于使用 range 轮询 channel 的事情。

package main

import "fmt"

func iter() func() (int, bool) {
    i := 0
        return func() (int, bool) {
        if i < 10 {
            i++
            return i, true
        }
        return i, false
    }
}

func main() {
    f := iter()
    for {
        v, ok := f()
        if !ok {
            break
        }
        fmt.Println(v)
    }
}

最佳答案

我认为没有办法避免检查 ok,但您可以重组它以避免丑陋的中断:

for v,ok := f(); ok; v,ok = f() {
    fmt.Println(v)
}

请注意,这仅适用于以下任一情况:

  1. 您有一个具有多个返回值的函数需要检查,或者

  2. 您有一个或多个只有一个返回值需要检查的函数

不幸的是,Go 不允许你做这样的事情

f := iter()
g := iter()
v,ok,v2,ok2 := f(), g(); ok && ok2; v,ok,v2,ok2 := f(), g() {
   // code
}

因此,如果您有一个包含多个函数的案例,您就会遇到 ifs 和 break,除非它们只返回一个值。

也就是说,(经过深思熟虑),在 Go 中编写迭代器的更惯用的方法是在 channel 上进行测距。考虑等效程序:

func Iterator(iterCh chan<- int) {
    for i := 0; i < 10; i++ {
       iterCh <- i
    }
    close(iterCh)
}

func main() {
    iter := make(chan int)
    go Iterator(iter)
    for v := range iter {
       fmt.Println(v)
    }
}

在这种情况下,不是返回 bool 值,而是在您完成发送值时关闭 channel 。此方法的缺点是,如果您想返回多个值,则必须制作某种结构以通过 channel 发送。

最后,如果您想在每次运行迭代器时将其包装一点以隐藏 channel 样板文件:

func Iter() <-chan int {
   iterChan := make(chan int)
   go iter(iterChan)
   return iterChan
}
func iter(iterCh chan<- int) {
    for i := 0; i < 10; i++ {
       iterCh <- i
    }
    close(iterCh)
}

func main() {
    for v := range Iter() {
       fmt.Println(v)
    }
}

这是初始实现的更多代码,但无需在每次要使用迭代器时手动声明 channel 。

关于go - 在 go 中轮询函数直到 ok != true 的惯用方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17867305/

相关文章:

go - 如何通过k8s.io客户端休息API请求传递容器名称

python - 数据重映射技术

postgresql - 如何使用postgresql角色连接数据库?

go - 依赖于 perl & sh 吗?

json - 如何将具有动态字段的 JSON 对象映射到 Go 结构

templates - Go Template ParseFiles 函数解析多个文件

go - 无法将 websocket 数据从 flutter 应用程序发送到服务器

go - 如何在不更改路径的情况下在 Go 中配置二进制名称

google-app-engine - App Engine 任务队列创建一批队列项并在 go lang 中每 10 秒执行一次

使用继承结构时 golang 类型不匹配