Golang básico - Controle de Fluxo - Complemento
Tags: go, tutorial, iniciante, portugues
Published: 2022-05-31 14:41:11

---
title: Golang básico - Controle de Fluxo - Complemento
published: true
description: 
tags: #go #golang #tutorial #iniciante #portugues
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wsrivp5deyklmxxxa6ok.jpeg
series: Golang básico
---
> Esse post faz parte de uma série onde pretendo compartilhar o básico essencial para desenvolver com GoLang.
> Esse em particular é um complemento do [Golang básico - Controle de Fluxo](https://dev.to/bgskurono/golang-basico-controle-de-fluxo-55i2)

Agora que já vimos como utilizar `IF`, `SWITCH` e `FOR` vamos ver algumas palavras reservadas do Go que são utilizadas para interromper ou acelerar a iteração do código.
## continue

A palavra reservada `continue` é específica para ser utilizada com `for`, e serve para pular para a próxima iteração:

```go
func main() {
	produtos := []produto{
		{
			nome:   "Produto Final",
			cor:    verde,
			status: publicado,
			criado: time.Now(),
		},
		{
			nome:   "Produto Teste",
			cor:    verde,
			status: rascunho,
			criado: time.Now(),
		},
	}

	for _, p := range produtos {
		if p.status == publicado {
			continue
		}
		fmt.Println(p)
	}
}
```
Executando esse código verá que somente o `Produto Teste` é impresso no `for`.

## break

Essa palavra reservada pode ser utilizada em `for`, `switch` e `select`. E ela serve para interromper a iteração do bloco e seguir para próxima instrução do código.

```go
// nesse for nenhum produto será impresso
for _, p := range produtos {
	if p.status == publicado {
		break
	}
	fmt.Println(p)
}
fmt.Println("Loop terminado")
```

```go
p := produto{
	nome:   "Produto Teste",
	cor:    verde,
	status: rascunho,
	criado: time.Now(),
}
// nenhum case será executado
switch p.status {
case publicado:
	fmt.Println("bloco publicado", p)
case rascunho:
	if p.cor == verde {
		break
	}
	fmt.Println("bloco rascunho", p)
case congelado:
	fmt.Println("bloco congelado", p)
}
fmt.Println("switch terminado")
```

## fallthrough

Essa é específica para ser utilizada com `switch`, em Go cada `case` do `switch` é exclusivo. Diferente de outras linguagens que caso precise ser exclusivo você precisa combinar o `case` + `break`.
Mas caso você tenha a necessidade de executar o mesmo case para mais de uma condição, pode fazer uso do `fallthrough` que transfere o controle para o `case` seguinte:

```go
// nesse exemplo ambos os cases serão executados
switch p.status {
case rascunho:
	fmt.Println("bloco rascunho")
	fallthrough
case congelado:
	fmt.Println("bloco congelado")
	fmt.Println("aplica lógica compartilhada entre produtos congelados e rascunhos")
}
fmt.Println("switch terminado")
```

## Label com `continue` e `break`

Em Go os blocos de códigos podem ter labels e podemos combinar o uso das palavras reservadas de controle com os labels. Isso acaba sendo útil quando temos operações aninhadas. Por exemplo:

```go
func main() {
	produtos := []produto{
		{
			nome:   "Produto Final",
			cor:    verde,
			status: publicado,
			criado: time.Now(),
		},
		{
			nome:   "Produto Teste",
			cor:    verde,
			status: rascunho,
			criado: time.Now(),
		},
	}

	for _, p := range produtos {
		switch p.status {
		case publicado:
			break
		case rascunho:
			fmt.Println("bloco rascunho")
			fallthrough
		case congelado:
			fmt.Println("aplica lógica compartilhada entre produtos congelados e rascunhos")
		}
		fmt.Println("aplica regra para produtos não publicados")
	}
	fmt.Println("Loop terminado")

}
```
Se você executar o código vai perceber que o break do switch não interrompe a execução do for. Com o uso de label fica assim:
```go
loopDeProduto:
	for _, p := range produtos {
		switch p.status {
		case publicado:
			break loopDeProduto
		case rascunho:
			fmt.Println("bloco rascunho")
			fallthrough
		case congelado:
			fmt.Println("aplica lógica compartilhada entre produtos congelados e rascunhos")
		}
		fmt.Println("aplica regra para produtos não publicados")
	}
	fmt.Println("Loop terminado")
```
Ou seja, com label você consegue controlar a iteração do for de dentro do switch. Mas poderia ser dois `for` aninhados também, ou qualquer outro bloco aninhado.

Bom esses recursos de controle são importantes de saber que existem, porém na minha opinião eles são bem evitáveis.
No geral quando você está fazendo operações aninhadas e precisando fazer um controle tão detalhado é um grande sinal de que talvez o seu código não esteja tão simples.
Sempre considere a expressividade do código, não o faça funcionar a qualquer custo!

## Resumo
* `continue` pula para próxima execução do `for`.
* `break` interrompe execução do bloco.
* `fallthrough` transfere controle para o case seguinte.
* Labels te possibilitam controlar de blocos aninhados.
* Sempre considere a expressividade do seu código.