Como Definir uma Variável em Go: Um Guia Visual e Prático
Aprenda variáveis em Go de forma visual: var, :=, valores zero, os tipos básicos e os seus tamanhos, conversões rígidas, estouro, constantes, strings como bytes vs. runes, os erros do compilador que você vai encontrar, saídas reais e exercícios com respostas.

Nesta página
Variáveis são o jeito de um programa lembrar das coisas: uma pontuação, um nome, um preço. O Go dá duas formas de criá-las, o var e o curtinho :=, e algumas regras que deixam o código Go incomumente seguro: toda variável começa com um valor sensato, os tipos nunca se misturam por acidente, e uma variável sem uso nem compila.
Neste guia você vai declarar variáveis de todos os jeitos que o Go permite, conhecer os tipos básicos e quanta memória cada um ocupa, converter entre eles e topar com as surpresas clássicas (estouro, decimais que não são exatos, strings cujo tamanho não é o que você espera), com as mensagens reais do compilador pelo caminho. Exercícios fecham o artigo.
Todas as saídas abaixo vêm de execuções reais com o Go 1.22 no Windows de 64 bits. As mensagens do compilador são em inglês; vamos traduzindo as importantes.
Declarando com var
A forma completa é a palavra-chave var, um nome e um tipo:
1package main
2
3import "fmt"
4
5func main() {
6 var idade int
7 idade = 35
8 fmt.Println(idade)
9
10 var nome string = "Ana Maria"
11 fmt.Println(nome)
12}35
Ana Maria
Repare na ordem: o tipo vem depois do nome, o contrário do C, do C++ e do Java. Lê-se da esquerda para a direita, como uma frase: "variável idade, um int". O int guarda números inteiros (sem casas decimais), como faz sentido para uma idade.
Toda variável começa com um valor zero
Em Go, uma variável declarada nunca tem lixo: ela começa com o valor zero do seu tipo.
1package main
2
3import "fmt"
4
5func main() {
6 var quantidade int
7 var preco float64
8 var nome string
9 var pronto bool
10 fmt.Printf("%v %v %q %v\n", quantidade, preco, nome, pronto)
11}0 0 "" false
Números começam em 0, strings em "" (o verbo %q imprime a string com as aspas, para você ver que está vazia) e booleanos em false. É uma grande diferença em relação ao C e ao C++, em que ler uma variável não inicializada é um erro. Em Go é sempre seguro, e muitas vezes é exatamente o que você quer: um contador que começa em zero não precisa de = 0.
Deixe o Go descobrir o tipo
Quando você dá um valor inicial, o Go descobre o tipo sozinho. Dá para tirar o tipo do var, ou usar a declaração curta de variável :=:
1package main
2
3import "fmt"
4
5func main() {
6 var cidade = "Lisboa"
7 altura := 1.65
8 ano := 2024
9 estaAberto := true
10 fmt.Printf("%v é um %T\n", cidade, cidade)
11 fmt.Printf("%v é um %T\n", altura, altura)
12 fmt.Printf("%v é um %T\n", ano, ano)
13 fmt.Printf("%v é um %T\n", estaAberto, estaAberto)
14}1Lisboa é um string
21.65 é um float64
32024 é um int
4true é um boolO verbo %T imprime o tipo de um valor. Um número inteiro vira int, um número com ponto decimal vira float64, texto vira string, e true/false vira bool. A variável continua com tipo fixo; você só não precisou escrever o tipo.
O := é o que você mais vai ver em código Go, mas ele tem duas regras:
- Só funciona dentro de funções. No nível do pacote (fora de qualquer função), use
var. - Precisa declarar pelo menos uma variável nova. Para mudar uma variável que já existe, use o
=simples.
Quebre as regras e o compilador avisa:
1package main
2
3import "fmt"
4
5func main() {
6 pontos := 10
7 pontos := 20
8 fmt.Println(pontos)
9}$ go run .
# ola
.\main.go:7:9: no new variables on left side of :=("Nenhuma variável nova do lado esquerdo do :=".)
1package main
2
3import "fmt"
4
5saudacao := "Olá"
6
7func main() {
8 fmt.Println(saudacao)
9}$ go run .
# ola
.\main.go:5:1: syntax error: non-declaration statement outside function body("Comando que não é declaração fora do corpo de uma função.") No nível do pacote, escreva var saudacao = "Olá".
Várias de uma vez, mudando e trocando
1package main
2
3import "fmt"
4
5var (
6 nomeDoApp = "Quiz de Go"
7 versao = 2
8)
9
10func main() {
11 largura, altura := 1920, 1080
12 fmt.Println(nomeDoApp, versao, largura, altura)
13
14 pontos := 10
15 pontos = pontos + 5
16 pontos += 20
17 pontos++
18 fmt.Println("Pontos:", pontos)
19
20 esquerda, direita := "esquerda", "direita"
21 esquerda, direita = direita, esquerda
22 fmt.Println(esquerda, direita)
23}Quiz de Go 2 1920 1080
Pontos: 36
direita esquerdavar ( … )agrupa várias declarações, comum no nível do pacote.largura, altura := 1920, 1080declara duas variáveis numa linha.=atribui um valor novo;+=,-=,*=e/=são atalhos, e o++soma um. (Em Go,pontos++é um comando sozinho na linha, não uma expressão que dá para usar dentro de outra.)esquerda, direita = direita, esquerdatroca dois valores numa linha, sem variável temporária: o Go calcula o lado direito primeiro.
Os tipos básicos e os seus tamanhos

1package main
2
3import (
4 "fmt"
5 "math"
6 "unsafe"
7)
8
9func main() {
10 var pequeno int8
11 var inteiro int
12 var decimal float64
13 var letra rune
14 var texto string
15 fmt.Println("int8:", unsafe.Sizeof(pequeno), "byte, até", math.MaxInt8)
16 fmt.Println("int:", unsafe.Sizeof(inteiro), "bytes, até", math.MaxInt)
17 fmt.Println("float64:", unsafe.Sizeof(decimal), "bytes")
18 fmt.Println("rune:", unsafe.Sizeof(letra), "bytes")
19 fmt.Println("string:", unsafe.Sizeof(texto), "bytes")
20}1int8: 1 byte, até 127
2int: 8 bytes, até 9223372036854775807
3float64: 8 bytes
4rune: 4 bytes
5string: 16 bytesOs que você mais vai usar:
intpara números inteiros. Em sistemas de 64 bits ele tem 8 bytes e guarda até cerca de 9,2 quintilhões. (Useint8,int16,int32ouint64quando precisar de um tamanho exato, e os tiposuintpara números que nunca são negativos.)float64para números com casas decimais.stringpara texto. Os 16 bytes são um ponteiro para o texto mais o tamanho dele; os caracteres em si ficam em outro lugar.boolparatrueoufalse.runepara um único caractere Unicode, escrito entre aspas simples:'A','ã'.
O Go nunca mistura tipos por acidente
Muitas linguagens convertem um int em decimal sem avisar quando você mistura os dois. O Go se recusa:
1package main
2
3import "fmt"
4
5func main() {
6 macas := 3
7 preco := 0.5
8 total := macas * preco
9 fmt.Println(total)
10}$ go run .
# ola
.\main.go:8:11: invalid operation: macas * preco (mismatched types int and float64)("Operação inválida: tipos que não combinam, int e float64.") Você converte explicitamente, escrevendo o tipo como se fosse uma chamada de função:
1package main
2
3import "fmt"
4
5func main() {
6 macas := 3
7 preco := 0.5
8 total := float64(macas) * preco
9 fmt.Println(total)
10
11 media := 7.9
12 fmt.Println(int(media))
13}1.5
7float64(macas) transforma 3 em 3.0. No sentido contrário, int(7.9) corta as casas decimais (dando 7, e não 8). Ser explícito quer dizer que você sempre vê onde acontece uma conversão. (O Go usa ponto, não vírgula, nos números.)
Números que não cabem
O Go pega alguns estouros já na compilação. Tente guardar 3 bilhões num int32:
1package main
2
3import "fmt"
4
5func main() {
6 var populacao int32 = 3000000000
7 fmt.Println(populacao)
8}$ go run .
# ola
.\main.go:6:24: cannot use 3000000000 (untyped int constant) as int32 value in variable declaration (overflows)Mas um estouro que acontece enquanto o programa roda dá a volta:
1package main
2
3import "fmt"
4
5func main() {
6 var nivel int8 = 127
7 nivel++
8 fmt.Println(nivel)
9}-128
Um int8 guarda de -128 a 127, então 127 + 1 dá a volta e vira -128, como um hodômetro. Em Go esse comportamento é bem definido (no C e no C++, o estouro com sinal é comportamento indefinido), mas quase nunca é o que você quer: escolha um tipo grande o bastante para os seus dados, o que normalmente quer dizer só usar int.
Constantes e contas exatas
Valores que nunca mudam são constantes, declaradas com const:
1package main
2
3import "fmt"
4
5const Pi = 3.14159
6
7func main() {
8 const diasPorSemana = 7
9 raio := 2.0
10 fmt.Println("Área:", Pi*raio*raio)
11 fmt.Println("Horas por semana:", diasPorSemana*24)
12
13 fmt.Println(0.1 + 0.2)
14 primeiro := 0.1
15 segundo := 0.2
16 fmt.Println(primeiro + segundo)
17}1Área: 12.56636
2Horas por semana: 168
30.3
40.30000000000000004As duas últimas linhas mostram um detalhe lindo do Go. 0.1 + 0.2 escrito com constantes é calculado pelo compilador com aritmética exata, dando exatamente 0.3. A mesma soma com variáveis float64 acontece durante a execução, em ponto flutuante binário, em que 0.1 e 0.2 não podem ser guardados de forma exata, então o resultado sai um tiquinho errado. Lição: não compare decimais com ==, e conte dinheiro em centavos inteiros.
Mudar uma constante é erro de compilação (cannot assign to Pi (neither addressable nor a map index expression)), e uma constante não pode guardar um valor calculado durante a execução. (Constantes que começam com letra maiúscula, como Pi, são exportadas pelo pacote, assim como as funções.)
Strings: bytes vs. caracteres
1package main
2
3import (
4 "fmt"
5 "unicode/utf8"
6)
7
8func main() {
9 palavra := "Olá"
10 fmt.Println(len(palavra))
11 fmt.Println(utf8.RuneCountInString(palavra))
12 fmt.Println(palavra + ", mundo!")
13 var inicial rune = 'O'
14 fmt.Println(inicial, string(inicial))
15}14
23
3Olá, mundo!
479 O
As strings do Go são guardadas como bytes UTF-8. O len conta bytes, então "Olá" dá 4 (o á ocupa dois bytes); o utf8.RuneCountInString conta caracteres. Isso importa muito em português, cheio de acentos! Um rune é um caractere, e na verdade é um número (79 é o código do O). O + junta strings.
A regra da variável sem uso
Como você viu no primeiro programa, o Go se recusa a compilar código com uma variável que você nunca usa:
1package main
2
3import "fmt"
4
5func main() {
6 var idade int = 35
7 nome := "Ada"
8 fmt.Println(nome)
9}$ go run .
# ola
.\main.go:6:6: idade declared and not usedApague, use, ou (enquanto experimenta) atribua ao identificador vazio: _ = idade.
Dando nome às variáveis
- Letras, dígitos e sublinhados, começando com letra ou sublinhado; os nomes diferenciam maiúsculas de minúsculas.
- O estilo do Go é o camelCase:
precoTotal,nomeDoUsuario. (Sublinhados são permitidos, mas não são o costume.) - Evite acentos nos nomes (
preco, nãopreço): o Go até aceita, mas é fonte de confusão. - Letra maiúscula quer dizer visibilidade: um
MaxUsuariosno nível do pacote é exportado para outros pacotes;maxUsuariosfica privado. - O Go prefere nomes curtos para escopos curtos:
ipara o índice de um laço ouerrpara um erro está bem por duas linhas, enquanto variáveis que vivem mais merecem nomes descritivos comosegundosPassados.
Sua vez: pratique
Tente fazer estes antes de espiar as respostas. Coloque cada programa no seu próprio módulo e rode com go run ..
Exercício 1: Adivinhe a saída (aquecimento). O que isto imprime?
1package main
2
3import "fmt"
4
5func main() {
6 var total int
7 var rotulo string
8 contagem := 3
9 contagem *= 4
10 fmt.Printf("[%v] [%q] %d %T\n", total, rotulo, contagem, contagem/5)
11 fmt.Println(contagem/5, float64(contagem)/5)
12}Exercício 2: Conserte o programa. Ele tem três erros. Ache-os rodando o programa.
1package main
2
3import "fmt"
4
5func main() {
6 preco := 9.99
7 quantidade := 3
8 quantidade := 4
9 var desconto float64
10 fmt.Println(preco * quantidade)
11}Exercício 3: Troque e mostre os tipos. Declare primeiro := "chá" e segundo := 42.5, imprima os dois com os seus tipos usando %v (%T), depois declare xicara, caneca := "pequena", "grande", troque as duas numa linha e imprima.
Exercício 4: Minutos em horas. Leia uma quantidade de minutos com o fmt.Scan e imprima em horas e minutos. Por exemplo, 135 minutos são 2 h 15 min.
Exercício 5: Média das notas (desafio). Três notas são int: 7, 8 e 10. Imprima a média com duas casas decimais (8.33), e não o resultado inteiro (8).
Quiz rápido
- O que uma variável
stringdeclarada guarda antes de receber valor? - Quando não dá para usar o
:=? - O que acontece com
macas * precoquandomacaséinteprecoéfloat64? - Por que
len("Olá")dá 4? - Qual é o tamanho de um
intnum computador de 64 bits?
Respostas
Exercício 1: total e rotulo guardam os valores zero; contagem vale 12; contagem/5 é uma divisão de int (2):
1package main
2
3import "fmt"
4
5func main() {
6 var total int
7 var rotulo string
8 contagem := 3
9 contagem *= 4
10 fmt.Printf("[%v] [%q] %d %T\n", total, rotulo, contagem, contagem/5)
11 fmt.Println(contagem/5, float64(contagem)/5)
12}[0] [""] 12 int
2 2.4Exercício 2: (1) quantidade := 4 redeclara uma variável: use quantidade = 4. (2) desconto é declarada e nunca usada: tire-a (ou use-a). (3) preco * quantidade mistura float64 e int: converta com float64(quantidade). Consertado:
1package main
2
3import "fmt"
4
5func main() {
6 preco := 9.99
7 quantidade := 3
8 quantidade = 4
9 fmt.Println(preco * float64(quantidade))
10}39.96Exercício 3: %v imprime o valor e %T o tipo; a troca usa a atribuição múltipla do Go:
1package main
2
3import "fmt"
4
5func main() {
6 primeiro := "chá"
7 segundo := 42.5
8 fmt.Printf("%v (%T)\n", primeiro, primeiro)
9 fmt.Printf("%v (%T)\n", segundo, segundo)
10
11 xicara, caneca := "pequena", "grande"
12 xicara, caneca = caneca, xicara
13 fmt.Println(xicara, caneca)
14}chá (string)
42.5 (float64)
grande pequenaExercício 4: A divisão inteira dá as horas, e o % os minutos que sobram:
1package main
2
3import "fmt"
4
5func main() {
6 var totalDeMinutos int
7 fmt.Print("Minutos: ")
8 fmt.Scan(&totalDeMinutos)
9 horas := totalDeMinutos / 60
10 minutos := totalDeMinutos % 60
11 fmt.Printf("%d h %d min\n", horas, minutos)
12}Minutos: 135
2 h 15 minMinutos: 59
0 h 59 minExercício 5: Somar os int dá 25; dividir por 3 como int daria 8, então converta a soma para float64 antes:
1package main
2
3import "fmt"
4
5func main() {
6 primeira, segunda, terceira := 7, 8, 10
7 soma := primeira + segunda + terceira
8 fmt.Println(soma / 3)
9 media := float64(soma) / 3
10 fmt.Printf("%.2f\n", media)
11}8
8.33Quiz: (1) A string vazia "", o seu valor zero. (2) Fora de funções (no nível do pacote), e quando nenhuma variável nova aparece do lado esquerdo. (3) Não compila: "mismatched types int and float64". Converta um dos lados explicitamente. (4) O len conta bytes, e o á ocupa dois bytes em UTF-8; o utf8.RuneCountInString dá 3 caracteres. (5) 8 bytes, guardando valores até cerca de 9,2 quintilhões.
Cola rápida
| Eu quero… | Escreva |
|---|---|
| Declarar com tipo | var idade int (começa em 0) |
| Declarar e inicializar | var idade int = 35 ou var idade = 35 |
| Declaração curta (em funções) | idade := 35 |
| Várias de uma vez | largura, altura := 1920, 1080 |
| Agrupar no nível do pacote | var ( nome = "Go"; versao = 2 ) |
| Mudar um valor | idade = 36, idade += 1, idade++ |
| Trocar | esquerda, direita = direita, esquerda |
| Converter tipos | float64(contagem), int(preco) |
| Uma constante | const Pi = 3.14159 |
| Imprimir valor e tipo | fmt.Printf("%v %T\n", x, x) |
| Bytes / caracteres de uma string | len(texto) / utf8.RuneCountInString(texto) |
| Ignorar um valor | _ = semUso |
Resumindo
As variáveis do Go são simples, e rígidas de um jeito que ajuda:
var nome tipodeclara;nome := valordeclara e deduz o tipo (só dentro de funções).- Toda variável começa no seu valor zero:
0,"",falseounil. Nada de lixo, nunca. - O
inttem 8 bytes em sistemas de 64 bits, ofloat64é o decimal padrão, e astringguarda bytes UTF-8. - Os tipos nunca se misturam por acidente: converta explicitamente com
float64(x)ouint(y). - Estouro de constante é erro de compilação; estouro na execução dá a volta (127 + 1 num
int8vira -128). - Constantes são exatas (
0.1 + 0.2dá 0.3), enquanto variáveisfloat64têm o arredondamento binário de sempre. - Variáveis sem uso não compilam, então o código Go fica arrumado.
Próximos passos na série: como instalar o Go no Linux e o laço for em Go. De volta ao começo: Seu Primeiro Programa em Go. Para ver o quadro geral, leia O Que É a Linguagem de Programação Go?
Leia a seguir

O Que É a Linguagem de Programação Rust? Um Guia Simples da Linguagem Rápida Que Não Deixa Você Travar
Um guia simples e sem jargões sobre o Rust, a linguagem tão rápida quanto o C que impede famílias inteiras de erros de memória antes de o programa rodar. Entenda a ideia de posse, por que gigantes da tecnologia o adotam e onde ele é usado.

O Que É a Linguagem de Programação Go? Um Guia Simples da Linguagem da Nuvem
Um guia simples e sem jargões sobre o Go, a linguagem simples e rápida que o Google criou para a nuvem. Entenda o que são goroutines, por que um programa Go é um arquivo só e como o Go passou a mover o Docker, o Kubernetes e boa parte da internet.

O Que É a Linguagem de Programação Ruby? Um Guia Simples da Linguagem Feita para a Felicidade
Um guia simples e sem jargões sobre o Ruby, a linguagem de programação feita para deixar os programadores felizes. Entenda por que o código Ruby parece inglês, como o Ruby on Rails move sites como GitHub e Shopify, e onde o Ruby brilha.
Comentários
Seja gentil e específico. Comentários com links de contas novas aparecem depois da análise de um moderador.