如何突破Golang中的嵌套循环?

时间:2018-08-24 01:07:23

标签: loops go

我有一个外循环和一个内循环,每个循环都在一个范围内迭代。我想在内部循环中满足条件时退出外部循环。

我有一个解决方案,它使用两个'break',一个在内部循环内部,一个在外部循环内部,就在内部循环外部。 Here it is(一个非常简单的示例):

package main

import (
    "fmt"
)

func main() {

    word := ""
    for _, i := range("ABCDE") {
        for _,j := range("ABCDE") {
            word = string(i) + string(j)
            fmt.Println(word)
            if word == "DC" {
                break
            }
        }
        if word == "DC" {
            break
        }
    }
    // More logic here that needs to be executed
}

此解决方案没有问题,但是对我来说,它看起来很修补而且很丑陋。有更好的方法吗?

在先前的解决方案中,我可以尝试在外循环之外设置另一个条件循环,并使用标签like so并继续使用。但是正如您所看到的,这种方法没有比带有中断解决方案的方法更优雅。

package main

import (
    "fmt"
)

func main() {

    word := ""

Exit:
    for word != "DC" {
        for _, i := range "ABCDE" {
            for _, j := range "ABCDE" {
                word = string(i) + string(j)
                fmt.Println(word)
                if word == "DC" {
                    continue Exit
                }
            }
        }
    }
    // More logic here that needs to be executed
}

我在这里看到了与其他语言(C,C#,Python等)有关的类似问题。但是我真正感兴趣的是golang构造(例如“ for select”)是否有任何技巧。

6 个答案:

答案 0 :(得分:6)

使用功能

package main

import (
    "fmt"
)

func getWord() string {
    word := ""
    for word != "DC" {
        for _, i := range "ABCDE" {
            for _, j := range "ABCDE" {
                word = string(i) + string(j)
                fmt.Println(word)
                if word == "DC" {
                    return word
                }
            }
        }
    }
}

func main(){
    word := getWord()
}

编辑:感谢@peterSO,他指出了细节上的一些错误并提供了这个游乐场https://play.golang.org/p/udcJptBW9pQ

答案 1 :(得分:5)

最直接的方法似乎是:

func main() {
    word := ""
    isDone := false
    for _, i := range("ABCDE") {
        for _,j := range("ABCDE") {
            word = string(i) + string(j)
            fmt.Println(word)
            isDone = word == "DC"
            if isDone {
                break
            }
        }
        if isDone {
            break
        }
    }
    //  other stuff
}

使用生成器的替代方法

不过,您也可以使用生成器来创建单词序列,如下所示:

func makegen () chan string {
    c:= make(chan string)
    go func () {
        for _, i := range ("ABCDE") {
            for _, j := range ("ABCDE") {
                c <- string(i) + string(j)
            }
        }
        close (c)
    }()

    return c
}


func main() {
    word := ""
    for word = range makegen() {
        fmt.Println (word)
        if word == "DC" {
          break
        }
    }
    // other code
}

答案 2 :(得分:5)

那去怎么样?

package main

import (
    "fmt"
)

func main() {

    word := ""

        for _, i := range "ABCDE" {
            for _, j := range "ABCDE" {
                word = string(i) + string(j)
                fmt.Println(word)
                if word == "DC" {
                    goto Exit
                }
            }
        }
    Exit: // More logic here that needs to be executed
}

答案 3 :(得分:2)

使用break {label}可以根据需要嵌套任何循环。只需将标签放在要打破的for循环之前 。这与执行goto {label}的代码非常相似,但我认为这有点优雅,但我认为是见仁见智。

package main

func main() {
    out:
    for i := 0; i < 10; i++ {
        for j := 0; j < 10; j++ {
            if i + j == 20 {
                break out
            }
        }
    }
}

更多详细信息:https://www.ardanlabs.com/blog/2013/11/label-breaks-in-go.html

答案 4 :(得分:1)

只需推迟您需要做的所有事情,然后照常返回即可。

package main

import (
    "fmt"
)

func main() {
    defer func() {
        // More logic here that needs to be executed
    }()

    word := ""

    for _, i := range "ABCDE" {
        for _, j := range "ABCDE" {
            word = string(i) + string(j)
            fmt.Println(word)
            if word == "DC" {
                return
            }
        }
    }
}

答案 5 :(得分:0)

将for循环包装在一个匿名的自调用函数中,然后在需要中断时返回

package main

func main() {
    func() {
        for i:= 0; i < 100; i++ {
            for j:= 0; j < 100; j++ {
                if (i == 5 && j == 5) {
                    return
                }
            }
        }
    }()
}