对于Go中重复函数调用的循环

时间:2014-04-26 13:05:47

标签: go

我正在对状态变化进行循环改变& condition在函数中定义,并且希望编写一个for语句,我只声明函数调用一次。

此代码有效,但重复message, flag = a.foo()感觉很乱。当初始语句与post语句相同时,是否有更有效的方法来编写for循环?

func (a *Example) foo() (string, bool) {
    // Function affects state of a
    // returns message on each step and flag if condition reached
}

func main() {
    // Step through each state change until flag is triggered
    for message, flag := a.foo(); flag; message, flag = a.foo() {
        fmt.Printf("%s\n", message)
    }
}

我希望有一种等同于它如此适合这样的if语句:

if message, flag := a.foo(); !flag {
    fmt.Printf("%s\n", message)
}

事实上,我非常希望我能改变它,如果是for,但是,唉,expected ';'. found '{'

我可能会问得太多,但如果有答案,我很乐意听到。感谢

3 个答案:

答案 0 :(得分:3)

据我所知,没有办法完全按照自己的意愿行事(尽管如果可能的话,我也会喜欢)。您可以使用“无限”循环并手动编写中断条件,尽管这也不是很好,例如:

func main() {
    for {
        msg, flag := a.foo()
        if flag {
            break
        }
        fmt.Printf(...)
    }
}

答案 1 :(得分:1)

如果您没有提前摆脱循环,一种选择是构建代码以使用频道和goroutine。因此,不要让Example.foo返回(string, bool),而是执行以下操作:

func (a *Example) foo() <-chan string {
    ch := make(chan string)
    go func() {
        // Send strings down the channel
        ch <- "first"
        ch <- "second"
        ...
        close(ch)
    }()
    return ch
}

然后,您可以使用以下内容循环显示值:

for message := range a.foo() {
    fmt.Printf("%s\n", message)
}

如上所述,如果您计划提前退出循环,则此模式不合适。如果你这样做,那么喂食通道的goroutine将被阻挡,并在内存中留下,直到程序退出。

答案 2 :(得分:0)

如果您不关心flagmessage的范围,您可以在for循环之前声明它们(即,如果您没有尝试制作标记和消息{ {3}})。

例如:

    var message string
    var flag bool = true

    // Step through each state change until flag is triggered
    for ; flag; message, flag = a.foo() {
        fmt.Printf("%s\n", message)
    }