Skip to main content


Operadores em Go


Os operadores são símbolos usados para fazer operações com valores. Eles aparecem em contas, comparações, atribuições e validações, exemplos simples:

soma := 10 + 5
maior := idade >= 18
ativo := usuarioAtivo && emailConfirmado


Operadores aritméticos


Os operadores aritméticos são usados para fazer contas. A tabela abaixo contém os operadores em Go.

OperadorUsoSignificado
+a + bsoma
-a - bsubtração
*a * bmultiplicação
/a / bdivisão
%a % bresto da divisão


Resto da divisão com %


O operador % retorna o resto de uma divisão inteira. No entanto, ele só funciona com tipos inteiros.


Resto da divisão é o valor que sobra quando uma divisão não é exata, exemplo: 10 ÷ 3 = 3 e sobra 1. Então, o resto da divisão de 10 por 3 é 1.


package main

import "fmt"

func main() {
numero := 10

// 10 dividido por 2 tem resto 0.
fmt.Println(numero % 2)
}

Resultado:

0

Ele é muito usado para verificar se um número é par ou ímpar, já que todo número par dividido por 2 não deixa resto. Já um número ímpar dividido por 2 sempre deixa resto.

package main

import "fmt"

func main() {
numero := 7

// Se o resto da divisão por 2 for 0, o número é par.
// Se for 1, é ímpar.
fmt.Println(numero % 2)
}

Resultado:

1


Operador + com string


O operador + também pode ser usado para concatenar strings, como já vimos. O ato de concatenar significa juntar textos.

package main

import "fmt"

func main() {
a := "Go"
b := "lang"

// Junta as duas strings.
fmt.Println(a + b)
}

Resultado:

Golang

Se quiser espaço entre as variáveis, ele precisa estar em alguma das strings:

package main

import "fmt"

func main() {
nome := "Ana"
sobrenome := "Silva"

// O espaço foi colocado no meio.
fmt.Println(nome + " " + sobrenome)
}

Resultado:

Ana Silva

Outro jeito de fazer isso é usando , vírgula:

package main

import "fmt"

func main() {
nome := "Ana"
sobrenome := "Silva"

// O espaço foi colocado no meio.
fmt.Println(nome, sobrenome)
}

O Go não concatena string com número automaticamente.

package main

func main() {
nome := "Ana"
idade := 20

// Erro.
// Não dá para juntar string com int usando +.
// mensagem := nome + idade

_, _ = nome, idade
}

Para montar texto com número, use fmt.Printf ou fmt.Sprintf.

package main

import "fmt"

func main() {
nome := "Ana"
idade := 20

// %v imprime o valor em formato padrão.
mensagem := fmt.Sprintf("%v tem %v anos", nome, idade)

fmt.Println(mensagem)
}


Operadores de comparação


Operadores de comparação são usados para comparar valores. O resultado sempre será um bool, ou seja, true ou false.

OperadorUsoSignificado
==a == bigual
!=a != bdiferente
>a > bmaior que
<a < bmenor que
>=a >= bmaior ou igual
<=a <= bmenor ou igual

Exemplo:

package main

import "fmt"

func main() {
idade := 18

// Compara se idade é igual a 18.
fmt.Println(idade == 18)

// Compara se idade é diferente de 18.
fmt.Println(idade != 18)

// Compara se idade é maior ou igual a 18.
fmt.Println(idade >= 18)
}

Cuidado para não confundir = com ==. O primeiro altera o valor da variável, já o segundo compara se o valor é igual a outro valor.



Operadores lógicos


Operadores lógicos trabalham com valores booleanos.

OperadorUsoSignificado
&&a && bE
||a || bOU
!!aNÃO

O operador && só retorna true quando os dois lados são true.

package main

import "fmt"

func main() {
idade := 20
temDocumento := true

// true && true resulta em true.
podeEntrar := idade >= 18 && temDocumento

fmt.Println(podeEntrar)
}

Resultado:

true

Já o operador || retorna true quando pelo menos um lado é true.

package main

import "fmt"

func main() {
temEmail := false
temTelefone := true

// Basta ter email ou telefone.
podeCadastrar := temEmail || temTelefone

fmt.Println(podeCadastrar)
}

Resultado:

true

O operador ! inverte o valor booleano.

package main

import "fmt"

func main() {
ativo := true

// !ativo inverte true para false.
fmt.Println(!ativo)
}

Resultado:

false


Operadores de atribuição


Atribuição é quando colocamos um valor em uma variável. O operador mais comum é =.

package main

import "fmt"

func main() {
idade := 20

// Altera o valor da variável.
idade = 21

fmt.Println(idade)
}

Também existem operadores de atribuição combinada.

OperadorExemploEquivale a
+=x += 2x = x + 2
-=x -= 2x = x - 2
*=x *= 2x = x * 2
/=x /= 2x = x / 2
%=x %= 2x = x % 2


Incremento e decremento


Go tem ++ e -- para trablhar com incremento e decremento.

package main

import "fmt"

func main() {
contador := 0

// Soma 1 ao contador.
contador++

fmt.Println(contador)

// Subtrai 1 do contador.
contador--

fmt.Println(contador)
}

Resultado:

1
0

Em Go, ++ e -- são comandos, não expressões. Isso significa que eles precisam ficar sozinhos em uma linha. O código abaixo não funciona:

package main

func main() {
contador := 0

// Erro em Go.
valor := contador++

_ = contador
}

O correto é separar:

package main

import "fmt"

func main() {
contador := 0

contador++
valor := contador

fmt.Println(valor)
}


Operadores entre tipos diferentes


Go não permite operações diretas entre tipos numéricos diferentes.

package main

func main() {
var a int = 10
var b int64 = 20

// Erro.
// a é int e b é int64.
resultado := a + b

_, _ = a, b
}

É necessário converter explicitamente.

package main

import "fmt"

func main() {
var a int = 10
var b int64 = 20

// Converte a para int64 antes da soma.
resultado := int64(a) + b

fmt.Println(resultado)
}

Isso também vale para int e float64.

package main

import "fmt"

func main() {
idade := 20
altura := 1.75

// Converte idade para float64 antes da soma.
resultado := float64(idade) + altura

fmt.Println(resultado)
}


Ordem das operações


O Go segue uma ordem parecida com a matemática. Multiplicação, divisão e resto vêm antes de soma e subtração.

package main

import "fmt"

func main() {
resultado := 10 + 2*3

fmt.Println(resultado)
}

Resultado:

16

O 2 * 3 foi calculado primeiro. Para mudar a ordem, devemos usar parênteses.

package main

import "fmt"

func main() {
resultado := (10 + 2) * 3

fmt.Println(resultado)
}

Resultado:

36

Quando a expressão começa a ficar grande, parênteses ajudam a deixar a intenção clara.



Go não tem operador ternário


Algumas linguagens têm operador ternário, algo como:

condicao ? valor1 : valor2

Go não tem esse operador, para isso, use if.

package main

import "fmt"

func main() {
idade := 20
status := ""

if idade >= 18 {
status = "maior de idade"
} else {
status = "menor de idade"
}

fmt.Println(status)
}

Ainda vamos estudar if no próximo tópico. Por enquanto, o ponto é só saber que Go prefere uma estrutura explícita em vez de ternário.



Estruturas de condição


Estruturas de condição são usadas quando o programa precisa tomar uma decisão. A ideia é simples, se uma condição for verdadeira, um bloco de código executa. Se não for, outro caminho pode ser seguido.


Em Go, as principais estruturas de condição são:

  • if
  • else
  • else if
  • switch


if


O if executa um bloco quando a condição é true.

package main

import "fmt"

func main() {
idade := 18

// A condição idade >= 18 retorna true ou false.
if idade >= 18 {
fmt.Println("Maior de idade")
}
}

// Resultado: Maior de idade

A condição do if não usa parênteses, mas pode usar, fica a gosto do freguês.

if idade >= 18 {
}

// Ou:
if (idade >= 18) {
}


if com else


O else define um bloco alternativo para o if. Esse bloco só é executado quando a condição do if não é atendida.

package main

import "fmt"

func main() {
idade := 16

if (idade >= 18) {
fmt.Println("Maior de idade")
} else {
fmt.Println("Menor de idade")
}
}

O else precisa ficar na mesma linha em que a chave do if fecha.



else if


O else if é usado quando existe mais de uma condição para ser testada.

package main

import "fmt"

func main() {
nota := 7

if (nota >= 9) {
fmt.Println("Excelente")
} else if (nota >= 7) {
fmt.Println("Aprovado")
} else if (nota >= 5) {
fmt.Println("Recuperação")
} else {
fmt.Println("Reprovado")
}
}

O Go testa de cima para baixo, quando encontra uma condição verdadeira, executa aquele bloco e ignora os próximos. Nesse exemplo, nota >= 7 é verdadeiro, então o programa imprime "Aprovado" e não testa mais os blocos seguintes.



if com declaração curta


O Go permite declarar uma variável dentro do próprio if.

package main

import "fmt"

func main() {
if idade := 20; (idade >= 18) {
fmt.Println("Maior de idade")
} else {
fmt.Println("Menor de idade")
}
}

A variável idade existe apenas dentro do if e do else. Isso é muito comum quando uma função retorna um valor que só será usado naquela verificação. Exemplo simples:

package main

import (
"fmt"
"strconv"
)

func main() {
texto := "25"

// numero e err só existem dentro desse if/else.
if numero, err := strconv.Atoi(texto); err == nil {
fmt.Println("Número convertido:", numero)
} else {
fmt.Println("Erro ao converter")
}
}

Nesse código, strconv.Atoi tenta converter uma string para int. Se der certo, err será nil. O nil representa ausência de valor em alguns tipos, e em tratamento de erro normalmente significa "não houve erro".



Condições com operadores lógicos


Podemos combinar condições usando &&, || e !.

package main

import "fmt"

func main() {
idade := 20
temDocumento := true

if (idade >= 18 && temDocumento) {
fmt.Println("Pode entrar")
} else {
fmt.Println("Não pode entrar")
}
}

O && significa "E", ou seja, as duas condições precisam ser verdadeiras. Também existe ||, que significa "OU":

package main

import "fmt"

func main() {
temEmail := false
temTelefone := true

if (temEmail || temTelefone) {
fmt.Println("Pode criar cadastro")
} else {
fmt.Println("Informe email ou telefone")
}
}

Nesse caso, basta uma das condições ser verdadeira.



switch


O switch é usado quando queremos comparar um valor contra várias possibilidades. Ele pode deixar o código mais limpo do que vários else if.

package main

import "fmt"

func main() {
dia := "segunda"

switch dia {
case "segunda":
fmt.Println("Começo da semana")
case "sexta":
fmt.Println("Quase fim de semana")
case "sábado", "domingo":
fmt.Println("Fim de semana")
default:
fmt.Println("Dia comum")
}
}

Resultado:

Começo da semana

O default executa quando nenhum case combina. Em Go, o switch não precisa de break no final de cada case como em algumas linguagens. Diferente de C, ele não continua executando os próximos casos automaticamente.



switch sem valor


Também podemos usar switch sem passar um valor principal, nesse caso, cada case vira uma condição.

package main

import "fmt"

func main() {
nota := 8

switch {
case (nota >= 9):
fmt.Println("Excelente")
case (nota >= 7):
fmt.Println("Aprovado")
case (nota >= 5):
fmt.Println("Recuperação")
default:
fmt.Println("Reprovado")
}
}

Resultado:

Aprovado

Esse formato é parecido com uma cadeia de if, else if e else.



Estruturas de repetição


Estruturas de repetição são usadas para executar um bloco de código várias vezes. Em Go, existe apenas uma estrutura principal de repetição, que é o for.



for tradicional


O for tradicional tem três partes:

for inicialização; condição; atualização {
}

+

Exemplo:

package main

import "fmt"

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

Resultado:

0
1
2
3
4


Simulando while com o for


Como Go não tem while, usamos o for com apenas uma condição.

package main

import "fmt"

func main() {
contador := 0

for contador < 5 {
fmt.Println(contador)

// Atualiza o contador para evitar loop infinito.
contador++
}
}

Esse formato significa, enquanto contador < 5 for verdadeiro, continue repetindo.



for infinito


Também existe for sem condição.

package main

import "fmt"

func main() {
contador := 0

for {
fmt.Println(contador)

contador++

if contador == 5 {
break
}
}
}

Esse loop seria infinito, mas usamos break para parar.



break


O break encerra o loop imediatamente.

package main

import "fmt"

func main() {
for i := 0; i < 10; i++ {
if i == 5 {
// Para o loop quando i for igual a 5.
break
}

fmt.Println(i)
}
}

Quando i chega em 5, o break interrompe a repetição.



continue


O continue pula para a próxima volta do loop.

package main

import "fmt"

func main() {
for i := 0; i < 5; i++ {
if i == 2 {
// Pula o restante desta volta.
continue
}

fmt.Println(i)
}
}

Quando i vale 2, o continue faz o loop seguir para a próxima repetição sem executar o fmt.Println.



for range


O range é usado para percorrer coleções, como strings, slices, arrays e maps. Ainda vamos estudar essas estruturas com calma, mas já dá para ver um exemplo simples com string.

package main

import "fmt"

func main() {
texto := "Go"

for indice, letra := range texto {
fmt.Println(indice, letra)
}
}

Resultado:

0 71
1 111

A letra apareceu como número porque, ao percorrer uma string com range, Go retorna o caractere como rune. Para imprimir como caractere, usamos %c:

package main

import "fmt"

func main() {
texto := "Go"

for indice, letra := range texto {
fmt.Printf("índice: %d | letra: %c\n", indice, letra)
}
}

Resultado:

índice: 0 | letra: G
índice: 1 | letra: o


Ignorando valores com _


Às vezes não queremos usar todos os valores retornados pelo range. Se quisermos apenas as letras:

package main

import "fmt"

func main() {
texto := "Go"

for _, letra := range texto {
fmt.Printf("%c\n", letra)
}
}

Resultado:

G
o