Desenvolvimento Back-end Go

Estruturas condicionais e de repetição na Go

Veremos nesse artigo sobre quais são e como podemos utilizar as estruturas condicionais e as estruturas de repetição na linguagem Go

há 1 ano 5 meses


Você sabia que a TreinaWeb é a mais completa escola para desenvolvedores do mercado?

O que você encontrará aqui na TreinaWeb?

Conheça os nossos cursos

No artigo anterior vimos sobre variáveis e constantes na Golang, agora nós vamos aprender quais são e como utilizar as estruturas condicionais e de repetição disponíveis na linguagem Go.

As estruturas condicionais estão diretamente ligadas ao processo de tomada de decisão dentro de um algoritmo, são elas que nos permitem alterar o fluxo de execução do código dependendo dos valores com os quais estamos trabalhando.

Já as estruturas de repetição, assim como o nome já diz, nos permitem repetir certos trechos de códigos um número determinado ou indeterminado de vezes, dependendo sempre de qual a condição de parada para tal estrutura.

Tanto as estruturas de repetição quanto as estruturas de condição irão trabalhar na sua maioria das vezes com valores booleanos, ou seja, true (verdadeiro) e false (falso). Caso você ainda não esteja familiarizado com os conceitos de estruturas condicionais e de repetição na lógica de programação, recomendo a leitura do artigo Estruturas condicionais e de repetição, que temos aqui no blog da TreinaWeb.

Estruturas condicionais

As estruturas condicionais possibilitam ao programa tomar decisões e alterar o seu fluxo de execução. Isso possibilita ao desenvolvedor o poder de controlar quais são as tarefas e trechos de códigos executados de acordo com diferentes situações.

As estruturas condicionais geralmente analisam expressões booleanas e, caso estas expressões sejam verdadeiras, um trecho do código é executado. No caso contrário, outro trecho do código é executado.

Estrutura if/else

if/else é uma estrutura de condição em que uma expressão booleana é analisada. Quando a condição que estiver dentro do if for verdadeira, ela é executada. Já o else é utilizado para definir o que é executado quando a condição analisada pelo if for falsa. Caso o if seja verdadeiro e, consequentemente, executado, o else não é executado.

if pode ser utilizado em conjunto com o else ou até mesmo sozinho, caso necessário.

Abaixo, temos um exemplo onde o if é utilizado em conjunto com o else.

package main

import "fmt"

func main() {
	idade := 18
	if idade >= 18 {
		// Se a váriavel idade for maior ou igual à 18 esse trecho de código será executado
		fmt.Println("Você é maior de idade!")
	} else {
		// Se a váriavel idade não for maior ou igual à 18 esse trecho de código será executado
		fmt.Println("Você é menor de idade!")
	}
}

Também podemos utilizar somente o if, não definindo um fluxo alternativo.

package main

import "fmt"

func main() {
	idade := 18
	if idade >= 18 {
		// Se a váriavel idade for maior ou igual à 18 esse trecho de código será executado
		fmt.Println("Você é maior de idade!")
	}
	// Se a váriavel idade não for maior ou igual à 18, nenhuma frase será exibida
}

Ainda é possível encadear múltiplas estruturas if/else caso necessário.

package main

import "fmt"

func main() {
	idade := 18
	if idade >= 18 {
		// Se a váriavel idade for maior ou igual à 18 esse trecho de código será executado
		fmt.Println("Você é maior de idade!")
	} else if idade >= 16 {
		// Se a váriavel idade não for maior ou igual à 18 mas for maior ou igual a 16 esse trecho de código será executado
		fmt.Println("Você não é maior de idade, mas já pode votar!")
	} else {
		// Se a váriavel idade não for maior ou igual à 18 esse trecho de código será executado
		fmt.Println("Você é menor de idade!")
	}
}

Estrutura switch/case

A estrutura condicional switch/case vem como alternativa, em momentos, em que temos que utilizar múltiplos if's no código. Múltiplos if/else encadeados tendem a tornar o código muito extenso, pouco legível e com baixo índice de manutenção.

switch/case testa o valor contido em uma variável, realizando uma comparação com cada uma das opções. Cada uma dessas possíveis opções é delimitada pela instrução case.

Podemos ter quantos casos de análise forem necessários e, quando um dos valores corresponder ao da variável, o código do case correspondente será executado. Caso a variável não corresponda a nenhum dos casos testados, o último bloco será executado, chamado de default (padrão).

package main

import "fmt"

func main() {
	mes := 1
	switch mes {
	case 1:
		fmt.Println("O mês é Janeiro!")
	case 2:
		fmt.Println("O mês é Fevereiro")
	case 3:
		fmt.Println("O mês é Março")
	case 4:
		fmt.Println("O mês é Abril")
	case 5:
		fmt.Println("O mês é Maio")
	case 6:
		fmt.Println("O mês é Junho")
	case 7:
		fmt.Println("O mês é Julho")
	case 8:
		fmt.Println("O mês é Agosto")
	case 9:
		fmt.Println("O mês é Setembro")
	case 10:
		fmt.Println("O mês é Outubro")
	case 11:
		fmt.Println("O mês é Novembro")
	case 12:
		fmt.Println("O mês é Dezembro")
	default:
		fmt.Println("Mês inválido")
	}
}

Na maioria das linguagens que possuem a estrutura switch/case, é necessário colocar a instrução break ao final de cada cláusula case, mas na linguagem Go, isso não é necessário.

Estruturas de repetição

Estruturas de repetição, também conhecidas como loops (laços), são utilizadas para executar repetidamente uma instrução ou bloco de instrução enquanto determinada condição estiver sendo satisfeita.

Na linguagem Go temos apenas uma estrutura de repetição, sendo a estrutura for, porém ela pode ser executada de maneiras diferentes, assim, tendo comportamentos diferentes.

Estrutura for com condição simples

for com condição simples é uma estrutura de repetição que irá repetir o bloco de código enquanto uma determinada condição for verdadeira, geralmente utilizamos essa estrutura quando não sabemos quantas vezes o trecho de código em questão deve ser repetido.

Essa estrutura possui a seguinte sintaxe:

for <condição> {
	// Trecho de código a ser repetido
}

Abaixo, temos um exemplo do for com condição simples. Neste exemplo, é pedido ao usuário que tente adivinhar o número. Enquanto o usuário não acerta o número, é pedido para que o usuário digite o valor que ele acha que é o correto. Perceba que nós temos um trecho de código que é sempre repetido, o pedido do número para o usuário. Mas, não sabemos exatamente quando o usuário vai acertar este número, ou seja, não sabemos exatamente quantas vezes o trecho de código será repetido. Nessa situação, o for com condição simples é a estrutura de repetição mais adequada.

package main

import "fmt"

func main() {
	numero := -1
	for numero != 10 {
		fmt.Print("Digite um número: ")
		fmt.Scanln(&numero)
		if numero < 10 {
			fmt.Println("Você errou, tente um número maior")
		} else if numero > 10 {
			fmt.Println("Você errou, tente um número menor")
		} else {
			fmt.Println("Você acertou")
		}
	}
}

Estrutura for clássica

for clássico é uma estrutura de repetição que trabalha com uma variável de controle e que repete o seu bloco de código até que uma determinada condição que envolve essa variável de controle seja falsa, geralmente utilizamos essa estrutura for quando sabemos a quantidade de vezes que o laço precisará ser executado.

for clássico possui a seguinte sintaxe:

for <variável de controle>; <condição de parada>; <incremento/decremento da váriavel de controle> {
	// Trecho de código a ser repetido
}

Quando utilizamos o for clássico, precisamos de uma variável para auxiliar a controlar a quantidade de repetições a serem executadas. Essa variável é chamada de variável de controle, declarada no primeiro argumento do for.

O segundo argumento do for clássico é utilizado para definir até quando o for será executado. Geralmente, trata-se de uma condição booleana em cima da variável de controle.

O terceiro argumento indica o quanto a variável de controle será modificada no final de cada execução dentro do for clássico.

Veja o exemplo abaixo:

package main

import "fmt"

func main() {
	for i := 1; i <= 10; i++ {
		fmt.Println("A váriavel i agora é:", i)
	}
}

A execução desse código causará a seguinte saída:

A váriavel i agora é:  1
A váriavel i agora é:  2
A váriavel i agora é:  3
A váriavel i agora é:  4
A váriavel i agora é:  5
A váriavel i agora é:  6
A váriavel i agora é:  7
A váriavel i agora é:  8
A váriavel i agora é:  9
A váriavel i agora é:  10

Isso acontece porque:

  • A variável de controle, que chamamos de i, tem como valor inicial 1;
  • No segundo argumento, onde escrevemos i <= 10, estamos dizendo que o bloco de código do for será executado enquanto o valor de i for menor ou igual a 10;
  • O terceiro argumento foi definido como i++, estamos dizendo que, no fim de cada execução do for, o valor de i será incrementado em 1. Isso quer dizer que, no fim da primeira execução, i irá de 1 para 2, na segunda execução, irá de 2 para 3, e assim por diante;
  • Com isso, o bloco de código do for será executado por 10 vezes, já que o i é iniciado em 1. A saída do código acima mostra que a mensagem foi escrita por 10 vezes, onde o i variou de 1 até 10.

Estrutura for sem condição

Também é possível utilizar a estrutura for sem passar nenhuma condição, utilizamos essa forma quando queremos criar um laço de repetição infinito.

Para essa estrutura utilizamos a seguinte sintaxe:

for {
	// Trecho de código a ser repetido
}

A primeiro momento parece ser estranho querer criar um laço de repetição infinito, mas em alguns casos isso é útil, por exemplo, podemos criar um programa que vai ficar executando por tempo indeterminado e que constantemente vai tentar ler informações de algum local, como um arquivo ou um sistema de filas.

Estrutura for com range

É muito comum as linguagens de programação possuírem uma estrutura de repetição chamada de foreach, basicamente a estrutura foreach serve para podermos percorrer os elementos de uma estrutura de dados de forma mais simples e menos verbosa.

Na Golang nós não temos essa estrutura, mas é possível termos o mesmo comportamento utilizando a palavra reservada range. O range permite iterar sobre os elementos de diferentes estruturas de dados.

Veja como percorríamos um array com um for clássico:

package main

import "fmt"

func main() {
	alunos := []string{"Cleyson", "Anna", "Autobele", "Hayssa"}
	for i := 0; i < 4; i++ {
		fmt.Println(alunos[i])
	}
}

No código acima foi criado um array de strings com quatro posições, em cada uma dessas tem o nome de um aluno, logo em seguida temos um for que irá fazer com que a variável controladora i vá de 0 a 3 e então utilizamos a variável i para fazer acesso aos elementos do array pelo índice e assim conseguir imprimir todos os seus valores.

O problema do uso do for clássico para essa tarefa é que não nos interessa o índice do array propriamente dito e sim apenas os seus valores internos, então podemos utilizar a estrutura for com o range para termos um código mais limpo.

Veja como ficaria o código acima refatorado para usarmos o for com range:

package main

import "fmt"

func main() {
	alunos := []string{"Cleyson", "Anna", "Autobele", "Hayssa"}
	for _, aluno := range alunos {
		fmt.Println(aluno)
	}
}

Basicamente o range vai permitir que possamos iterar sobre os elementos de uma estrutura de dados com o auxílio do for, outro ponto interessante é que o range retorna dois valores, sendo o primeiro o índice da estrutura de dados e o segundo o próprio elemento.

Como no exemplo acima só nos interessava o elemento e não o seu índice, o primeiro valor foi ignorado utilizando o caractere _ (underscore).

Em ambos os casos o resultado impresso no terminal será:

Cleyson
Anna
Autobele
Hayssa

Conclusão

Como vimos nesse artigo a Golang possui todas as estruturas de condição e de repetição básicas que existem na maioria das linguagens de programação, vimos quais são essas estruturas e como podemos utilizá-las em nossos programas.

Por fim, caso queira aprender mais sobre a Go e sua infinidade de recursos saiba que aqui na TreinaWeb temos o curso Go Básico que possui 05h30 de vídeo e um total de 37 exercícios.

Veja quais são os tópicos abordados durante o curso Go Básico:

  • Compreender a sintaxe básica da Golang;
  • Compreender conceitos básicos envolvidos na Go, como ponteiros de memória;
  • Utilizar as estruturas básicas da linguagem, como declaração de variáveis;
  • Utilizar as principais estruturas de conjuntos da Go, como arrays, slices e maps;
  • Entender as principais funções built-in, como make(), new(), panic(), recover() e defer;
  • Organizar o código em pacotes e utilizar os principais pacotes disponibilizados pela linguagem;
  • Entender como podemos utilizar concorrência com a Golang, inclusive com técnicas como os channels;
  • Entender o que são as structs na Go e como podemos utilizar um pouco de orientação a objetos com a linguagem;
  • Realizar operações de I/O no sistema operacional, como a criação e escrita de arquivos.

Autor(a) do artigo

Cleyson Lima
Cleyson Lima

Professor, programador, fã de One Piece e finge saber cozinhar. Cleyson é graduando em Licenciatura em Informática pelo IFPI - Campus Teresina Zona Sul, nos anos de 2019 e 2020 esteve envolvido em vários projetos coordenados pela secretaria municipal de educação da cidade de Teresina, onde o foco era introduzir alunos da rede pública no mundo da programação e robótica. Hoje é instrutor dos cursos de Spring na TreinaWeb, mas diz que seu coração sempre pertencerá ao Python.

Todos os artigos

Artigos relacionados Ver todos