How to break out of nested loops in Go?

I have an outer and inner loop, each iterating over a range. I want to exit the outer loop when a condition is satisfied inside the inner loop.

I have a solution which works using two 'break's, one inside the inner loop and one inside the outerloop, just outside the inner loop (a very simplified case for demonstration):

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
}

Go Playground

There is no problem with this solution, but it just looks patched and ugly to me. Is there a better way to do this?

I can try and have another for conditional loop outside the outer loop in the previous solution and have a label and use continue with the label. But as you can see, this approach isn't any more elegant than the solution with break.

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
}

Go Playground

I have seen similar questions here pertaining to other languages (C, C#, Python etc). But what I am really interested to see is whether there is any trick with Go constructs such as 'for select'.


Solution 1:

Use break {label} to break out of any loop as nested as you want. Just put the label before the for loop you want to break out of. This is fairly similar to the code that does a goto {label} but I think a tad more elegant, but matter of opinion I guess.

package main

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

More details: https://www.ardanlabs.com/blog/2013/11/label-breaks-in-go.html

Solution 2:

use function

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
                }
            }
        }
    }
    return word
}

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

Edit: thanks to @peterSO who points on some mistakes in the details and provides this playground https://play.golang.org/p/udcJptBW9pQ