猿问

轮询功能的惯用方式,直到 ok != true in go

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


有没有比if !ok每次都检查更惯用的方式来轮询它。我正在考虑类似于使用range.


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)

    }

}


Smart猫小萌
浏览 174回答 2
2回答

白衣非少年

我认为没有办法避免检查确定,但您可以对其进行重组以避免丑陋的中断:for v,ok := f(); ok; v,ok = f() {&nbsp; &nbsp; fmt.Println(v)}应该注意的是,这仅适用于以下任一情况:您有一个带有多个返回值要检查的函数,或者您有一个或多个只有一个返回值的函数需要检查不幸的是,Go 不会让你做这样的事情f := iter()g := iter()v,ok,v2,ok2 := f(), g(); ok && ok2; v,ok,v2,ok2 := f(), g() {&nbsp; &nbsp;// code}因此,如果您有一个包含多个函数的案例,除非它们只返回一个值,否则您会被 if 和中断所困扰。也就是说,(以及反思),在 Go 中编写迭代器的更惯用的方法是遍历通道。考虑等价的程序:func Iterator(iterCh chan<- int) {&nbsp; &nbsp; for i := 0; i < 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp;iterCh <- i&nbsp; &nbsp; }&nbsp; &nbsp; close(iterCh)}func main() {&nbsp; &nbsp; iter := make(chan int)&nbsp; &nbsp; go Iterator(iter)&nbsp; &nbsp; for v := range iter {&nbsp; &nbsp; &nbsp; &nbsp;fmt.Println(v)&nbsp; &nbsp; }}在这种情况下,不要返回布尔值,只需在完成发送值时关闭通道即可。这种方法的缺点是如果你想返回多个值,你必须创建某种结构来通过通道发送。最后,如果你想在每次运行迭代器时稍微包装一下以隐藏通道样板:func Iter() <-chan int {&nbsp; &nbsp;iterChan := make(chan int)&nbsp; &nbsp;go iter(iterChan)&nbsp; &nbsp;return iterChan}func iter(iterCh chan<- int) {&nbsp; &nbsp; for i := 0; i < 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp;iterCh <- i&nbsp; &nbsp; }&nbsp; &nbsp; close(iterCh)}func main() {&nbsp; &nbsp; for v := range Iter() {&nbsp; &nbsp; &nbsp; &nbsp;fmt.Println(v)&nbsp; &nbsp; }}这是初始实现的更多代码,但是每次要使用迭代器时都不必手动声明通道。

动漫人物

我看不出你的例子与文件结束之前阅读的常见习语有何不同。例如,package mainimport (&nbsp; &nbsp; "bytes"&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "io"&nbsp; &nbsp; "strings")func main() {&nbsp; &nbsp; buf := bytes.NewBufferString("line1\nline2")&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; line, err := buf.ReadString('\n')&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if err != io.EOF {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if len(line) == 0 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; line = strings.TrimSuffix(line, "\n")&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(line)&nbsp; &nbsp; }}输出:line1line2你的例子对我来说看起来很惯用。
随时随地看视频慕课网APP

相关分类

Go
我要回答