Domine Loops For em Golang: Guia Completo com Exemplos!

Explorando os Loops `for` em Golang: Um Guia Prático com Exemplos

Nos últimos tempos, linguagens de programação como Rust, Golang e TypeScript têm ganhado enorme popularidade entre os desenvolvedores. Se você tem interesse em desenvolvimento back-end e DevOps, o Golang surge como uma excelente opção para investir seu tempo e esforço.

Para quem está iniciando na programação, dominar as estruturas de repetição (loops) é um dos primeiros passos essenciais. Em Golang, a construção de loop predominante é o `for`. Vamos desvendar todos os seus segredos e mostrar como utilizá-lo para simular outros tipos de loops.

Prepare-se para começar!

Sintaxe do Loop `for` em Golang

A estrutura básica de um loop `for` em Golang é a seguinte:


for inicialização; condição; atualização {
    // código a ser executado
}

Onde:

  • `inicialização`: define o ponto de partida da variável de controle do loop.
  • `condição`: estabelece o critério para a continuidade do loop. Enquanto a condição for verdadeira, o bloco de código dentro do loop será repetido. Caso contrário, a execução do loop é interrompida.
  • `atualização`: especifica como a variável de controle é modificada a cada iteração (geralmente um incremento ou decremento).

💡 Vale notar que essa estrutura é semelhante à do loop `for` em C, porém sem os parênteses.

O fluxo de execução de um loop `for` em Golang é bastante direto, e para entendê-lo melhor, vamos trabalhar com exemplos práticos. Você pode usar uma instalação local do Golang ou o Go Playground para executar os códigos junto comigo.

Exemplos de Loop `for` em Golang

Com a sintaxe que acabamos de revisar, vamos criar nosso primeiro loop `for`. Este exemplo imprimirá os números de 1 a 5, em incrementos de 1:


package main

import "fmt"

func main() {
	fmt.Println("Loop for:")
	num := 5
	for i := 1; i <= num; i++ {
		fmt.Println(i)
	}
}

Aqui, a variável de controle `i` é inicializada com 1, a condição para a execução do loop é `i <= 5`, e a cada iteração `i` é incrementada em 1. O resultado é:


//Saída
Loop for:
1
2
3
4
5

Agora, vejamos um outro exemplo. Este loop começará em 5 e contará de forma decrescente até 1. A condição será que a variável de controle seja maior ou igual a 1. Portanto, a cada iteração, ela será decrementada em 1.


package main

import "fmt"

func main() {
	fmt.Println("Loop for:")
	num := 5
	for i := num; i >= 1; i-- {
		fmt.Println(i)
	}
}

Como esperado, a saída será:


//Saída
Loop for:
5
4
3
2
1

Qual o Escopo da Variável de Loop?

É importante entender que o escopo da variável de controle do loop (`i`, em nossos exemplos) é restrito ao bloco do loop `for`. Isso significa que ela não estará acessível fora desse bloco.

Para comprovar isso, vamos tentar acessar o valor de `i` fora do loop:


package main

import "fmt"

func main() {
	fmt.Println("Loop for:")
	num := 5
	for i := 1; i <= num; i++ {
		fmt.Println(i)
	}
	fmt.Println(i)

}

Como previsto, o compilador acusará um erro, informando que `i` não está definida (e que seu escopo é limitado ao loop `for`):


// Saída
./prog.go:11:14: undefined: i

Loop `for` Infinito em Golang

É possível criar loops infinitos em Go? A resposta é sim!

Com base no fluxo de execução de um loop `for`:

  • O bloco de código dentro do loop continua sendo executado enquanto a condição for avaliada como verdadeira.
  • Quando a condição se torna falsa, a execução do loop é interrompida.
  • Portanto, se a condição nunca se tornar falsa (ou for sempre verdadeira), teremos um loop infinito.

É possível utilizar o loop `for` sem as etapas de inicialização, condição e atualização, sem gerar erros de sintaxe. Ao fazer isso, criamos um loop que será executado indefinidamente:


package main

import "fmt"

func main() {
	for {
	   fmt.Println("executando...")
	}
}

//Saída
executando...
executando...
executando...
executando...
executando...
//e isso continuará para sempre!

Neste exemplo, a condição de loop é `num > 0`. Como o valor de `num` nunca é alterado dentro do loop, a condição será sempre verdadeira, resultando em um loop infinito.


package main

import "fmt"

func main() {
	num := 5
	for num > 0 {
		fmt.Println(num)
	}
}

//Saída
5
5
5
5
5
5
//e isso continuará para sempre!

Como o Golang oferece apenas o `for` como estrutura de loop, podemos usar o `for` para simular os comportamentos dos loops `while` e `do-while`. Veja como:

Simulando o Loop `while` com `for`

Um loop `while` geralmente segue esta estrutura:


// inicializa a variável de controle do loop
while (condição){
    // código a ser executado
    // atualiza a variável de controle do loop
}

Se você se lembra, no exemplo do loop `for` infinito, escrevemos um loop `for` sem inicialização, condição e atualização:


for {
// este é o loop infinito mais simples
}

Para simular o loop `while`, podemos modificar o `for` para conter apenas a condição, da seguinte forma:


//inicializa a variável de controle do loop
for condição {
 // código a ser executado
 // atualiza a variável de controle do loop
}

Aqui está o código para emular um loop `while`, equivalente ao primeiro loop `for` que escrevemos:


package main

import "fmt"

func main() {
	fmt.Println("Simulando loop while")
	num := 5
	for num > 0 {
		fmt.Println(num)
		num--
	}
}

//Saída
Simulando loop while
5
4
3
2
1

Simulando o Loop `do-while` com `for`

Se você já programou em C, conhece a estrutura do loop `do-while`:


// inicializa a variável de controle do loop
do {
//código
// atualiza a variável de controle do loop
} while(condição);

A diferença principal entre o `while` e o `do-while` é que o `while` verifica a condição *antes* de executar o bloco de código, enquanto o `do-while` a verifica *depois*. Isso significa que, em um loop `while`, se a condição inicial for falsa, o código nunca será executado. Já no `do-while`, o código será executado pelo menos uma vez, mesmo que a condição inicial seja falsa.

Para emular o comportamento de um loop `do-while`, podemos:

  • Criar um loop `for` infinito.
  • Utilizar uma instrução condicional `if` com a condição correta para sair do loop.

Suponha que queremos emular um loop `do-while` onde a condição para executar o código é `num < 0`. Assim, podemos usar um loop `for` e sair do loop caso `num >= 0`.


package main

import "fmt"

func main() {
	fmt.Println("Simulando loop do-while")
	num := 5
	for {
		fmt.Println("loop sendo executado...")
		if num >= 0 {
			break
		}
	}
}

💡 Note que as condições `num < 0` para executar o loop e `num >= 0` para sair do loop são equivalentes.

Embora a condição `num > 0` seja inicialmente falsa (já que `num` é 5), o código dentro do loop é executado uma vez, simulando o comportamento do loop `do-while`.


//Saída
Simulando loop do-while
loop sendo executado...

Percorrendo Arrays com o Loop `for`

Ao percorrer arrays em Golang com um loop `for` e a palavra-chave `range`, podemos acessar tanto os índices quanto os elementos. Isso é semelhante à função `enumerate` em Python.

Neste exemplo, criamos um array de inteiros chamado `numArray` e o percorremos utilizando um loop `for`:


package main

import "fmt"

func main() {
	fmt.Println("Percorrendo um array")
	numArray := []int{3, 7, 0, 10, 8, 9}
	for idx, num := range numArray {
		fmt.Println("No índice", idx, ": ", num)
	}
}

Como podemos ver, é possível acessar tanto o índice quanto o elemento em cada posição:


//Saída
Percorrendo um array
No índice 0 :  3
No índice 1 :  7
No índice 2 :  0
No índice 3 :  10
No índice 4 :  8
No índice 5 :  9

Utilizando `defer` em Loops `for`

Em Golang, a palavra-chave `defer` permite adiar a execução de uma função. Embora seja geralmente usada para tarefas como liberação de recursos e tratamento de erros, é interessante entender como `defer` funciona dentro de um loop `for`. Vejamos o que acontece quando utilizamos `defer` em um loop `for` para adiar as chamadas da função `Println()`:


package main

import "fmt"

func main() {
	fmt.Println("Loop for:")
	num := 5
	for i := 1; i <= num; i++ {
		defer fmt.Println(i)
	}
}

💬 Quando uma chamada de função é adiada, ela é colocada em uma pilha e executada na ordem LIFO (último a entrar, primeiro a sair). Essa execução acontece apenas após o término da função que contém a instrução `defer`.

Portanto, `fmt.Println(5)` será executado primeiro, e `fmt.Println(1)` será executado por último:


//Saída
Loop for:
5
4
3
2
1

Conclusão

Aqui está um resumo do que aprendemos neste tutorial:

  • Em Golang, os loops `for` são construídos com a sintaxe: `for inicialização; condição; atualização { //código}`.
  • O fluxo de execução do loop `for` é bastante simples: a variável de controle é inicializada uma vez, a condição é verificada para determinar se o bloco de código deve ser executado e a atualização modifica a variável de controle após cada iteração.
  • O escopo da variável de controle é limitado ao bloco do loop, não sendo acessível fora dele.
  • Embora Golang forneça apenas a estrutura de loop `for`, podemos simular os comportamentos dos loops `while` e `do-while` com ele.
  • Outras aplicações do loop `for` incluem percorrer arrays e adiar chamadas de função dentro do loop usando `defer`.

Agora que você domina os loops `for` em Golang, explore como eles são utilizados em outras linguagens, como Python. Bons estudos! 🎉