Ícone do site Aprenda Golang

Como colocar rótulo em looping

Night-Shining Clouds are Getting Brighter by NASA Goddard Photo and Video is licensed under CC-BY 2.0

Não sei vocês, mas a primeira vez que “ouvi” falar dessa feature foi há algumas semanas atrás. Mais uma vez, não foi em nenhum blog post ou vídeo do youtube que ví a utilização dessa feature, mas sim no código fonte da linguagem.

Com a minha experiência em outras linguagens, sempre que tinha que lidar com um looping dentro de outro, a maneira mais comum de fazer um “break” dos 2 loopings era com uma variável de controle.

Nessa estratégia, o looping interno altera essa variável e faz um break. Com seu valor alterado, o looping externo também faz um “break”.

Veja o exemplo abaixo:

func main() {
    var exit bool
    for !exit {
        for i := 0; i < 10; i++ {
            fmt.Println(i)

            if i == 7 {
                exit = true
                break
            }
        }
    }
}

Eu sei, eu sei… esse código não tem pé, nem cabeça, mas ele consegue demonstrar a questão do looping interno ter um “break” que deve refletir no looping externo.

Um outro exemplo, seria um looping infinito com um select interno para lidar com múltiplos channels.

func main() {
    var exit bool
    for !exit {
        select {
            case <-c:
                exit = true
            case v <- num:
                fmt.Println(v)
        }
    }
}

Ambos os códigos funcionam. Porém, como eu disse no inicio do post, algumas semanas atrás eu descobri uma nova forma de fazer isso.

Essa estratégia é chamada de rótulo e consiste um “rotular” o looping externo. Veja o exemplo.

func main() {
loop:
    for {
        for i := 0; i < 10; i++ {
            fmt.Println(i)

            if i == 7 {
                break loop
            }
        }
    }
}

Embora o resultado final seja o mesmo, dessa forma fica muito mais claro que o break irá sair do looping externo também.

Para o segundo exemplo, o código ficaria assim:

func main() {
loop:
    for {
        select {
            case <-c:
                break loop
            case v <- num:
                fmt.Println(v)
        }
    }
}

Deixem suas dúvidas nos comentários.

Até a próxima!


Se inscreva na nossa newsletter

* indicates required
Sair da versão mobile