Go: Variáveis e tipos de dados em Go

Última atualização: 2026-08-26

As variáveis são a base de um programa — o Go utiliza uma sintaxe minimalista para tornar as declarações de variáveis claras e seguras.

A filosofia de design por trás do sistema de tipos do Go: Explícito em vez de implícito. Isso significa que toda 変数 possui um tipo bem definido, permitindo que o compilador detecte mais de 90% dos erros em tempo de compilação. Nesta lição, você aprenderá toda a 構文 para declarar variáveis no Go.

1. Você aprenderá


2. A história real de um engenheiro full-stack

(1) Problema: Depuração tarde da noite causada pela tipagem dinâmica

Alice é uma engenheira que mudou do Python para o Go. Ela ingressou recentemente na empresa e assumiu a responsabilidade por um módulo de registro de usuários:

“O gerente de produto disse: ‘Após o lançamento, os dados dos usuários estavam uma bagunça. Algumas pessoas inseriram 1º de janeiro de 2024 como data de nascimento, outras inseriram “ontem” e outras ainda inseriram null — metade dos dados no banco de dados não pôde ser analisada.’”

Ela deu uma olhada no código e descobriu que a tipagem dinâmica do Python era a culpada:

PYTHON
# Python: variable types can change at any time
birthday = "1990-01-01"
birthday = 1990  # integer suddenly valid
birthday = None  # None also valid
birthday = ["today"]  # list also valid!

A mesma variável pode ser uma string, um inteiro, None ou uma lista em diferentes partes do código — não há nenhum mecanismo para evitar essa confusão.

(2) Solução em Go

Alice reescreveu o modelo de usuário em Go:

GO
// user.go
package main

import "fmt"

type User struct {
    Name      string  // string
    Age       int     // integer
    Height    float64 // float
    IsActive  bool    // boolean
    Birthday  string  // ISO 8601 date string
}

func main() {
    user := User{
        Name:     "Alice",
        Age:      28,
        Height:   165.5,
        IsActive: true,
        Birthday: "1996-05-12",
    }

    // Want to change `Age` to a string? You'll get a compile-time error!
    // user.Age = "twenty-eight"  // ❌ cannot use "twenty-eight" as int

    fmt.Printf("User: %s, Age: %d, Height: %.1fcm\n",
        user.Name, user.Age, user.Height)
}

Resultado:

TEXT 📖 Somente leitura
User: Alice, Age: 28, Height: 165.5cm

(3) Benefícios: Detecta 90% dos erros durante a compilação

Dimensão Python (tipagem dinâmica) Go (tipagem estática e forte)
Verificação de tipos em tempo de compilação ❌ Nenhuma ✅ Rigorosa
Erro de tipo em tempo de execução Frequente Raro
Autocompletar do IDE Fraco Forte
Segurança da refatoração Baixa Alta
Armadilha de valor nulo (Nenhum/nulo) Comum Proteção contra o mecanismo de valor zero
💡 Dica: O “mecanismo de valor zero” do Go garante que toda variável tenha um valor padrão razoável no momento da declaração, eliminando 80% dos problemas com ponteiros nulos.


3. Declaração de variáveis: var e :=

O Go oferece duas maneiras de declarar variáveis: a var palavra-chave (padrão) e a := declaração abreviada (forma abreviada).

(1) Declaração da palavra-chave var (método padrão)

var pode ser usado dentro de funções ou no nível do pacote, e há três maneiras de escrevê-lo:

GO
// Method 1: Declare a variable with an explicit type
var name string = "Alice"

// Method 2: Declare a variable and omit the type (the type is inferred from the value)
var name = "Alice"

// Method 3: Declare only; initialize to zero value
var name string  // name = ""

(2) ▶ Exemplo: Comparação entre três formas de escrever var

GO
package main

import "fmt"

func main() {
    // Method 1: Explicit Type + Initialization
    var userName string = "Alice"
    var userAge int = 28

    // Method 2: Type Inference
    var userEmail = "alice@example.com"

    // Method 3: Declare only; rely on the default value
    var userBio string  // ""

    fmt.Println(userName, userAge, userEmail, userBio)
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
Alice 28 alice@example.com

(3) := Declaração curta (a mais comum)

:= é um sintaxe simplificada em Go; só pode ser usado dentro de funções e infere automaticamente o tipo:

GO
package main

import "fmt"

func main() {
    // Short declaration: variable_name := value
    name := "Alice"       // inferred as string
    age := 28             // inferred as int
    height := 165.5       // inferred as float64
    isActive := true      // inferred as bool

    fmt.Printf("%s is %d years old, height %.1f, active: %v\n",
        name, age, height, isActive)
}

Saída:

TEXT 📖 Somente leitura
Alice is 28 years old, height 165.5, active: true

(4) var vs := — qual devo escolher?

Cenário Abordagem recomendada Motivo
Variáveis no nível do pacote var := Não podem ser usadas fora de funções
Variáveis locais dentro de uma função := Conciso; economiza 4 caracteres
Deve ter valor zero var x int := Deve ser inicializado ao mesmo tempo
Requer uma conversão de tipo explícita var x int = int(3.14) A conversão de tipo está claramente visível
Declarações em lote var (...) := não suporta declarações em lote

4. Tipos de dados básicos do Go

O Go possui 14 tipos de dados básicos, que são divididos em quatro categorias principais com base em sua finalidade.

(1) Tipos inteiros

100%
graph TB
    A[Integer Types] --> B[Signed int]
    A --> C[Unsigned uint]
    A --> D[Byte type]
    A --> E[Special rune]

    B --> B1[int<br/>at least 32 bits]
    B --> B2[int8 / int16 / int32 / int64]

    C --> C1[uint<br/>at least 32 bits]
    C --> C2[uint8 / uint16 / uint32 / uint64]

    D --> D1[byte = uint8<br/>emphasizes byte]
    E --> E1[rune = int32<br/>emphasizes Unicode code point]
Tipo Tamanho Faixa Aplicações típicas
int 32 ou 64 bits (dependendo da plataforma) -2^31 a 2^31-1 ou maior Tipo inteiro padrão
int8 8 bits -128 a 127 Números inteiros de intervalo pequeno
int32 32 bits -2^31 a 2^31-1 Tamanho fixo multiplataforma
int64 64 bits -2^63 a 2^63-1 Números inteiros grandes, carimbos de data/hora
uint 32 ou 64 bits 0 a 2^32-1 ou maior Sem sinal por padrão
byte 8 bits 0–255 byte, caractere ASCII
rune 32 bits ponto de código Unicode caractere Unicode único

(2) ▶ Exemplo: A diferença entre int e int64

GO
package main

import (
    "fmt"
    "unsafe"
)

func main() {
    var a int = 100
    var b int64 = 200

    fmt.Printf("a (int) size: %d bytes\n", unsafe.Sizeof(a))
    fmt.Printf("b (int64) size: %d bytes\n", unsafe.Sizeof(b))

    // You cannot directly add `int` and `int64`!
    // sum := a + b  // ❌ mismatched types int and int64

    // An explicit conversion is required
    sum := a + int(b)
    fmt.Println("sum:", sum)
}
▶ Experimente

Saída (em plataformas de 64 bits):

TEXT 📖 Somente leitura
a (int) size: 8 bytes
b (int64) size: 8 bytes
sum: 300

(3) Tipos de ponto flutuante

Tipo Tamanho Precisão Aplicações típicas
float32 32 bits ~7 dígitos significativos Computação científica, gráficos
float64 64 bits ~15 dígitos significativos Tipo padrão de ponto flutuante

(4) Tipo booleano

GO
var isActive bool = true
var hasPermission bool  // zero value = false

(5) Tipo String

GO
var greeting string = "Hello, Go!"
var emptyString string  // zero value = "" (empty string)
var multiLine string = `Line 1
Line 2
Line 3`  // backticks support multi-line strings

(6) Tabela de referência rápida para 14 tipos

Categoria Tipo Valor zero
Número inteiro int / int8 / int16 / int32 / int64 0
Inteiros sem sinal uint / uint8 / uint16 / uint32 / uint64 0
Byte/Caractere byte (=uint8) / rune (=int32) 0
Ponto flutuante float32 / float64 0,0
Booleano bool falso
String string ""

5. O mecanismo exclusivo de valor zero do Go

Não há variáveis “não inicializadas” em Go — toda variável possui um valor padrão razoável no momento em que é declarada.

(1) ▶ Exemplo: Valores zero de todos os tipos

GO
package main

import "fmt"

func main() {
    var i int
    var f float64
    var b bool
    var s string
    var p *int  // pointer zero value is nil

    fmt.Printf("int: %d\n", i)
    fmt.Printf("float64: %f\n", f)
    fmt.Printf("bool: %v\n", b)
    fmt.Printf("string: %q\n", s)  // %q shows quoted string, empty string shows ""
    fmt.Printf("pointer: %v\n", p)
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
int: 0
float64: 0.000000
bool: false
string: ""
pointer: <nil>

(2) Valores zero em comparação com outras linguagens

Tipo Valor zero Java Python C/C++
Inteiro 0 0 Não existe Indefinido (valor inválido)
Ponto flutuante 0,0 0,0 Não existe Indefinido
Booleano falso falso Falso Indefinido
String "" nulo "" Indefinido
Ponteiro nil null None NULL (mas sujeito a ponteiros inválidos)
🔥 Erro comum: Em C/C++, variáveis não inicializadas contêm valores aleatórios na memória — essa é a causa principal de 90% dos bugs de estouro de buffer. O Go elimina esse problema no nível da linguagem por meio de seu mecanismo de valor zero.


6. const Constantes e iota Enumerações

(1) Use const para declarar constantes

As constantes são determinadas em tempo de compilação, não podem ser modificadas e devem ser de tipos básicos:

GO
const Pi = 3.14159
const AppName = "web-tutorial"
const MaxConnections = 1000

(2) Enumeração Iota: a elegante forma de enumeração do Go

iota é um contador constante no Go que começa em 0 e incrementa automaticamente em 1 a cada linha:

GO
package main

import "fmt"

const (
    Sunday    = iota  // 0
    Monday            // 1
    Tuesday           // 2
    Wednesday         // 3
    Thursday          // 4
    Friday            // 5
    Saturday          // 6
)

func main() {
    fmt.Printf("Sunday=%d Monday=%d Saturday=%d\n", Sunday, Monday, Saturday)
}

Saída:

TEXT 📖 Somente leitura
Sunday=0 Monday=1 Saturday=6

(3) ▶ Exemplo: Incremento personalizado de iota (códigos de status HTTP)

GO
package main

import "fmt"

const (
    StatusOK       = iota * 100  // 0
    StatusRedirect               // 100
    StatusClientError            // 200
    StatusServerError            // 300
)

func main() {
    fmt.Printf("OK=%d Redirect=%d ClientError=%d ServerError=%d\n",
        StatusOK, StatusRedirect, StatusClientError, StatusServerError)
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
OK=0 Redirect=100 ClientError=200 ServerError=300

(4) Uso avançado do iota: máscaras de bits (permissões de arquivo)

GO
package main

import "fmt"

const (
    ReadPermission   = 1 << iota  // 1 << 0 = 1
    WritePermission               // 1 << 1 = 2
    ExecutePermission             // 1 << 2 = 4
)

func main() {
    // Permission Combination: Read + Write = 1 | 2 = 3
    rw := ReadPermission | WritePermission
    fmt.Printf("Read=%d Write=%d Execute=%d RW=%d\n",
        ReadPermission, WritePermission, ExecutePermission, rw)
}

Saída:

TEXT 📖 Somente leitura
Read=1 Write=2 Execute=4 RW=3
💡 Dica: iota é a única sintaxe no Go que se aproxima de uma “enum”, mas não é tão rígida quanto os tipos enum no Python ou no Java. Se você precisar de maior segurança de tipos em um ambiente de produção, pode definir seus próprios tipos.


7. Conversão explícita de tipos

O Go não permite conversões implícitas de tipo — todas as conversões devem ser declaradas explicitamente. Isso reflete o princípio do Go de “explícito em vez de implícito”.

(1) Conversão de tipos numéricos

GO
package main

import "fmt"

func main() {
    var i int = 42
    var f float64 = float64(i)      // int → float64
    var u uint = uint(f)            // float64 → uint

    fmt.Printf("i=%d f=%v u=%d\n", i, f, u)

    // Truncation example: Converting a float to an int results in the loss of the decimal part
    var pi float64 = 3.14159
    var truncated = int(pi)
    fmt.Printf("pi=%.5f truncated=%d\n", pi, truncated)
}

Saída:

TEXT 📖 Somente leitura
i=42 f=42 u=42
pi=3.14159 truncated=3

(2) Conversão de strings: o pacote strconv

GO
package main

import (
    "fmt"
    "strconv"
)

func main() {
    // String → Number
    n, err := strconv.Atoi("123")
    fmt.Printf("n=%d err=%v\n", n, err)

    // Number → String
    s := strconv.Itoa(456)
    fmt.Printf("s=%s (type: %T)\n", s, s)

    // String → float
    f, _ := strconv.ParseFloat("3.14", 64)
    fmt.Printf("f=%f\n", f)

    // float → string (specified precision)
    fmt.Println(strconv.FormatFloat(3.14159, 'f', 2, 64))  // "3.14"
}

Saída:

TEXT 📖 Somente leitura
n=123 err=<nil>
s=456 (type: string)
f=3.140000
3.14

(3) Conversão implícita x conversão explícita

Cenário Java/C++ Go
int + float Convertido automaticamente para float Erro de compilação; deve ser explícito
int32 + int64 Convertido automaticamente para int64 Erro de compilação
int para string Implícito Requer strconv.Itoa()
⚠️ Observação: A conversão de tipos rigorosa do Go pode parecer prolixa, mas, na verdade, evita erros clássicos encontrados em Java e C++, como “erros de arredondamento” e “estouro de inteiros”.


8. fmt: Formatar a saída

(1) Verbos comuns de formatação

Verbo Significado Tipos aplicáveis
%d Inteiro decimal int, int8/16/32/64
%f Número de ponto flutuante float32, float64
%s string string
%v Formato padrão para qualquer tipo Qualquer tipo
%T Tipo Qualquer tipo
%t Booleano bool
%q String entre aspas string, runa
%x Hexadecimal int, []byte
%p Endereço do ponteiro ponteiro
%% Símbolo de porcentagem literal

(2) ▶ Exemplo: Demonstração completa do fmt.Printf

GO
package main

import "fmt"

func main() {
    name := "Alice"
    age := 28
    height := 165.5
    isActive := true
    hobbies := []string{"coding", "reading", "hiking"}

    fmt.Printf("Name: %s\n", name)              // %s string
    fmt.Printf("Age: %d\n", age)                // %d integer
    fmt.Printf("Height: %.1f cm\n", height)     // %.1f float with 1 decimal
    fmt.Printf("Active: %t\n", isActive)        // %t boolean
    fmt.Printf("Hobbies: %v\n", hobbies)        // %v default format
    fmt.Printf("Name type: %T\n", name)         // %T type
    fmt.Printf("100%% complete!\n")             // %% literal %

    // %v Advanced usage: %+v displays the field name (struct), %#v displays Go syntax
    fmt.Printf("hobbies: %#v\n", hobbies)
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
Name: Alice
Age: 28
Height: 165.5 cm
Active: true
Hobbies: [coding reading hiking]
Name type: string
100% complete!
hobbies: []string{"coding", "reading", "hiking"}

(3) A diferença entre Print, Println e Printf

Função Terminação de saída Casos de uso
fmt.Print() Sem quebra de linha Saída contínua
fmt.Println() Quebras de linha automáticas + separadas por espaço Depuração simples
fmt.Printf() Não insere uma nova linha; requer \n Saída formatada
fmt.Sprintf() Retorna uma string; não exibe Concatena strings

9. Exemplo completo: Formulário de cadastro do usuário

Reúna todos os conceitos-chave desta lição e crie um coletor de dados para registro de usuários:

GO
// main.go
package main

import (
    "fmt"
    "strconv"
)

// Defining User Role Enumerations Using Iota
const (
    RoleGuest     = iota // 0 Guest
    RoleUser             // 1 Regular User
    RoleAdmin            // 2 Admin
    RoleSuperAdmin       // 3 Super Admin
)

func main() {
    // 1. Use the := short declaration for user information
    name := "Alice"
    age := 28
    height := 165.5
    isActive := true
    role := RoleUser

    // 2. Explicit Type Conversion
    ageAsFloat := float64(age)
    heightAsString := strconv.FormatFloat(height, 'f', 1, 64)

    // 3. const Constants
    const MaxLoginAttempts = 5

    // 4. fmt: Formatted Output
    fmt.Println("========================================")
    fmt.Println("      User Registration Form")
    fmt.Println("========================================")
    fmt.Printf("Name:           %s\n", name)
    fmt.Printf("Age:            %d (%.0f years old)\n", age, ageAsFloat)
    fmt.Printf("Height:         %s cm\n", heightAsString)
    fmt.Printf("Active:         %t\n", isActive)
    fmt.Printf("Role:           %d (User)\n", role)
    fmt.Printf("Max Attempts:   %d\n", MaxLoginAttempts)
    fmt.Printf("Type Check:     name is %T, age is %T\n", name, age)
    fmt.Println("========================================")

    // 5. Demonstration of Zero Values for Variables
    var uninitializedAge int
    fmt.Printf("\nUninitialized age (zero value): %d\n", uninitializedAge)
}

Resultado esperado:

TEXT 📖 Somente leitura
========================================
      User Registration Form
========================================
Name:           Alice
Age:            28 (28 years old)
Height:         165.5 cm
Active:         true
Role:           1 (User)
Max Attempts:   5
Type Check:     name is string, age is int
========================================

Uninitialized age (zero value): 0
🔥 Erro comum: strconv.Atoi("abc") retornará um erro, que não deve ser ignorado. Sintaxe correta: n, err := strconv.Atoi("abc"); if err != nil { ... }. A lição 8 aborda mais detalhadamente o tratamento de erros.


❓ Perguntas Frequentes

P: O que é melhor, var ou :=? R: Recomendamos usar := dentro de funções — é conciso e garante a inicialização; variáveis no nível do pacote devem usar var. O bytecode gerado por ambos é exatamente o mesmo; trata-se apenas de sintaxe simplificada.

P: O tamanho do int do Go varia entre plataformas de 32 bits e 64 bits. Que problemas isso pode causar? R: Ele tem 8 bytes em plataformas de 64 bits e 4 bytes em plataformas de 32 bits. Se você precisar serializar seus dados (por exemplo, para JSON ou um banco de dados), recomenda-se especificar explicitamente int32 ou int64 para evitar problemas de compatibilidade entre plataformas.

P: O Go não possui uma palavra-chave enum. Como se cria uma enumeração? R: Use const + iota. Embora não seja tão rigorosa quanto a enum class do Java, é suficiente. Se você precisar de segurança de tipos, pode usar um tipo personalizado como type Role int junto com um conjunto de constantes.

P: O valor de iota começa em 0. Ele pode começar em 1? R: Sim. Use _ = iota para pular o 0, ou iota + 1: const (A = iota + 1; B; C), o que resulta em A=1, B=2, C=3. Isso é comumente usado em cenários em que os valores precisam começar em 1, como códigos de status HTTP e meses.

P: Por que o Go não suporta conversão implícita de tipos? R: A equipe do Go acredita que “explícito é melhor do que implícito”. As conversões implícitas são a causa principal de muitos bugs em Java e C++ (como a perda de precisão ao misturar operações int e long). A conversão rigorosa de tipos do Go torna o código mais legível e resulta em menos bugs.

P: Como se faz a conversão entre string e []byte? R: []byte(s) converte uma string em uma fatia de bytes (copiando os dados); string(b) converte uma fatia de bytes em uma string. Essas funções são comumente utilizadas em cenários de E/S de rede e criptografia. Observação: []byte é adequado para modificação, enquanto string é adequado para uso somente leitura.

P: Posso usar caracteres chineses nos nomes das variáveis? R: Tecnicamente, sim (o Go suporta identificadores Unicode), mas isso é fortemente desaconselhado. Nomes de variáveis em chinês dificultam a colaboração entre equipes internacionais no código, e algumas ferramentas (como linters e IDEs) podem não reconhecê-los. Sempre use convenções de nomenclatura em inglês (camelCase ou sublinhados).

P: É possível obter o endereço de uma constante? R: Não. As constantes são definidas em tempo de compilação e não possuem um endereço de memória em tempo de execução. &Pi resultará em um erro de compilação.


📖 Resumo


📝 Exercícios

  1. Exercício básico (Dificuldade ⭐): Declare 5 variáveis (nome/idade/altura/éEstudante/média) usando as sintaxes var e := e imprima seus valores e tipos.

  2. Exercício avançado (Dificuldade ⭐⭐): Use iota para definir quatro constantes de códigos de status HTTP (200/404/500/503) e escreva uma função handleRequest(code int) que retorne o texto correspondente (por exemplo, “OK”, “Não encontrado”, “Erro interno do servidor” ou “Serviço indisponível”) com base no código de status.

  3. Problema de desafio (Dificuldade ⭐⭐⭐): Escreva um conversor de unidades: receba como entrada uma temperatura em Fahrenheit e retorne a temperatura em Celsius (fórmula: C = (F - 32) × 5/9). Requisitos: (1) Use fmt.Scanf para ler a entrada; (2) Use strconv.ParseFloat para a conversão de tipos; (3) Trate entradas inválidas (retorne um erro).

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%