Variáveis e Tipos de Dados
Imagine que você está cozinhando na cozinha: variáveis são caixas de armazenamento rotuladas — o rótulo é o nome e a caixa contém dados; tipos de dados são os formatos das caixas — caixas redondas contêm sopa, caixas quadradas contêm pratos, e você não pode misturá-las. Go é muito rigoroso com o gerenciamento de "caixas": você deve declarar qual caixa (tipo) precisa, qual conteúdo colocar (atribuição), e até caixas vazias têm conteúdos padrão (valores zero).
1. Conceitos Fundamentais
1.1 Declaração de Variáveis: var vs :=
Go oferece duas maneiras de declarar variáveis:
| Método | Sintaxe | Caso de Uso | Escopo |
|---|---|---|---|
var |
var nome int |
Variáveis de nível de pacote, tipos explícitos necessários | Dentro/fora de funções |
Declaração curta := |
nome := 10 |
Variáveis locais, inferência de tipo | Apenas dentro de funções |
Diferenças principais:
varpode ser declarado sem atribuição (usa valor zero automaticamente);:=requer atribuição.varpode ser declarado fora de funções;:=só pode ser usado dentro de funções.:=é uma abreviação para declaração + atribuição; pelo menos uma variável à esquerda deve ser nova.
1.2 Tipos de Dados Básicos
| Categoria | Tipo | Descrição | Exemplo |
|---|---|---|---|
| Inteiro | int, int8, int16, int32, int64 |
Inteiros com sinal | var a int = 42 |
| Inteiro sem sinal | uint, uint8, uint16, uint32, uint64 |
Inteiros não negativos | var b uint = 100 |
| Ponto flutuante | float32, float64 |
Decimais (padrão float64) |
var c float64 = 3.14 |
| Booleano | bool |
true / false |
var d bool = true |
| String | string |
Sequência de bytes imutável | var e string = "hello" |
| Byte | byte |
Apelido para uint8, representa um byte |
var f byte = 'A' |
| Caractere Unicode | rune |
Apelido para int32, representa um ponto de código Unicode |
var g rune = '中' |
Tipos dependentes de plataforma: int e uint são 32 bits em sistemas de 32 bits e 64 bits em sistemas de 64 bits. No desenvolvimento diário, int é suficiente na maioria dos casos.
1.3 Mecanismo de Valor Zero
Quando uma variável é declarada mas não atribuída em Go, ela é automaticamente inicializada com um valor zero, não null ou indefinido:
| Tipo | Valor Zero |
|---|---|
Inteiro (int, uint, etc.) |
0 |
Ponto flutuante (float32, float64) |
0.0 |
Booleano (bool) |
false |
String (string) |
"" (string vazia) |
| Ponteiro, slice, map, channel, função, interface | nil |
Este é o mecanismo de segurança do Go — você nunca obtém uma variável "sem valor", evitando muitos erros de ponteiro nulo.
1.4 Constantes e iota
constdeclara constantes cujos valores são determinados em tempo de compilação e não podem ser alterados depois.iotaé um gerador de constantes que auto-incrementa a partir de 0 dentro de um blococonst, adequado para definir enums.
1.5 Conversão de Tipos
Go não suporta conversão implícita de tipos; tipos diferentes devem ser convertidos explicitamente:
var i int = 42
var f float64 = float64(i) // int → float64
var u uint = uint(f) // float64 → uint
1.6 Saída Formatada do Pacote fmt
fmt é o pacote de formatação mais utilizado do Go. Funções principais:
| Função | Propósito | Exemplo |
|---|---|---|
fmt.Println |
Imprimir com quebra de linha | fmt.Println("hello") |
fmt.Printf |
Impressão formatada (sem quebra de linha) | fmt.Printf("valor=%d", 42) |
fmt.Sprintf |
Formatar para string (sem imprimir) | s := fmt.Sprintf("%d", 42) |
Especificadores de formato comuns: %d (inteiro), %f (float), %s (string), %t (booleano), %T (tipo), %v (valor genérico), %q (string com aspas).
2. Sintaxe/Uso Básico
Declaração de Variáveis
// Método 1: declaração var (dentro/fora de funções)
var nome string // Declaração, valor zero ""
var idade int = 25 // Declaração com atribuição
var pontuacao = 98.5 // Inferência de tipo como float64
// Método 2: declaração curta := (apenas dentro de funções)
cidade := "São Paulo" // Declaração com atribuição, inferido como string
contagem := 100 // Inferência de tipo como int
// Declaração em lote
var (
largura int = 10
altura int = 20
area float64
)
var mas não usá-la, o compilador Go reportará declared and not used. Esta é a filosofia de design do Go: código morto não é permitido. O mesmo se aplica à declaração curta :=.
Declaração de Constantes
// Constante única
const Pi = 3.14159
const Linguagem string = "Go"
// Constantes em lote + enumeração iota
const (
Domingo = iota // 0
Segunda // 1
Terca // 2
Quarta // 3
Quinta // 4
Sexta // 5
Sabado // 6
)
iota só é válido dentro de um bloco const e auto-incrementa em 1 para cada nova linha. Se uma linha usa _ para pular, iota ainda incrementa.
Conversão de Tipos
var i int = 100
var f float64 = float64(i) // Conversão explícita: int → float64
var s string = string(rune(i)) // int → rune → string (nota: não transforma número em string)
// Maneira correta de converter número para string:
s2 := fmt.Sprintf("%d", i) // "100"
string(65) produz o caractere "A" (código ASCII), não "65". Para converter um número para string decimal, use fmt.Sprintf ou strconv.Itoa.
3. Código de Exemplo
Exemplo 1: Uso Básico (Dificuldade ⭐)
Cenário: Declare variáveis de diferentes tipos, imprima seus valores e tipos.
package main
import "fmt"
func main() {
// ========== Declaração de Variáveis ==========
// 1. Declaração var + tipo explícito
var nome string = "Alice"
var idade int = 28
// 2. Declaração var + inferência de tipo (compilador infere o tipo do valor)
salario := 15000.5 // Inferido como float64
// 3. Declaração de variável curta (mais comum)
empregado := true
cidade := "São Paulo"
// 4. Demonstração de valor zero — declare sem atribuição
var intPadrao int // Valor zero: 0
var floatPadrao float64 // Valor zero: 0
var boolPadrao bool // Valor zero: false
var stringPadrao string // Valor zero: ""
// ========== Saída de Impressão ==========
fmt.Println("=== Informações Pessoais ===")
fmt.Printf("Nome: %s (Tipo: %T)\n", nome, nome)
fmt.Printf("Idade: %d (Tipo: %T)\n", idade, idade)
fmt.Printf("Salário: %.1f (Tipo: %T)\n", salario, salario)
fmt.Printf("Empregado: %t (Tipo: %T)\n", empregado, empregado)
fmt.Printf("Cidade: %s (Tipo: %T)\n", cidade, cidade)
fmt.Println("\n=== Demonstração de Valor Zero ===")
fmt.Printf("Valor zero int: %d\n", intPadrao)
fmt.Printf("Valor zero float64: %v\n", floatPadrao)
fmt.Printf("Valor zero bool: %t\n", boolPadrao)
fmt.Printf("Valor zero string: %q\n", stringPadrao) // %q mostra string com aspas
}
Saída:
=== Informações Pessoais ===
Nome: Alice (Tipo: string)
Idade: 28 (Tipo: int)
Salário: 15000.5 (Tipo: float64)
Empregado: true (Tipo: bool)
Cidade: São Paulo (Tipo: string)
=== Demonstração de Valor Zero ===
Valor zero int: 0
Valor zero float64: 0
Valor zero bool: false
Valor zero string: ""
Pontos-Chave:
%Timprime o tipo subjacente de uma variável.%qadiciona aspas a strings, facilitando distinguir strings vazias de não vazias durante a depuração.- O mecanismo de valor zero garante que as variáveis sempre tenham um valor definido, o que é uma garantia de segurança importante no Go.
Exemplo 2: Uso Intermediário (Dificuldade ⭐⭐)
Cenário: Usando constantes, iota para definir enums e conversão de tipos na prática.
package main
import "fmt"
// ========== Enum iota: Definir Permissões de Papel ==========
type Role int // Tipo personalizado com int como tipo subjacente
const (
Guest Role = iota // 0: Convidado
Member // 1: Membro
Admin // 2: Administrador
SuperAdmin // 3: Super Admin
)
// Implementar método String() para Role para facilitar a impressão
func (r Role) String() string {
names := [...]string{"Guest", "Member", "Admin", "Super Admin"}
if int(r) < len(names) {
return names[r]
}
return "Papel Desconhecido"
}
// ========== Uso Avançado de iota: Flags de Permissão Bitwise ==========
type Permission int
const (
Read Permission = 1 << iota // 1 (001)
Write // 2 (010)
Execute // 4 (100)
)
// ========== Conversão de Tipos na Prática ==========
func main() {
// --- Uso de enum iota ---
var userRole Role = Admin
fmt.Printf("Papel do usuário: %s (Valor: %d)\n", userRole, userRole)
// --- Combinação de permissão bitwise ---
userPerm := Read | Write // Permissões combinadas: Leitura + Escrita = 3 (011)
fmt.Printf("\nValor da permissão do usuário: %d (Binário: %03b)\n", userPerm, userPerm)
fmt.Printf("Tem permissão de leitura? %t\n", userPerm&Read != 0)
fmt.Printf("Tem permissão de execução? %t\n", userPerm&Execute != 0)
// --- Conversão de tipos ---
var temperatura float64 = 36.6
var intTemp int = int(temperatura) // float64 → int (trunca, não arredonda)
fmt.Printf("\nTemp corporal: %.1f°C → Parte inteira: %d\n", temperatura, intTemp)
// Número → string (duas maneiras)
var codigo int = 65
char := string(rune(codigo)) // Método 1: Converter para caractere Unicode correspondente → "A"
numStr := fmt.Sprintf("%d", codigo) // Método 2: Converter para string numérica → "65"
fmt.Printf("Número %d → Caractere: %s, String: %q\n", codigo, char, numStr)
// --- Strings e bytes/caracteres ---
s := "Hello,世界"
fmt.Printf("\nString %q tamanho: %d bytes\n", s, len(s))
fmt.Println("Travessia byte a byte (não recomendado para CJK):")
for i := 0; i < len(s); i++ {
fmt.Printf(" [%d] %d %c\n", i, s[i], s[i])
}
fmt.Println("Travessia rune a rune (trata corretamente CJK):")
for i, r := range s {
fmt.Printf(" [%d] %U '%c'\n", i, r, r)
}
}
Saída:
Papel do usuário: Admin (Valor: 2)
Valor da permissão do usuário: 3 (Binário: 011)
Tem permissão de leitura? true
Tem permissão de execução? false
Temp corporal: 36.6°C → Parte inteira: 36
Número 65 → Caractere: A, String: "65"
String "Hello,世界" tamanho: 12 bytes
Travessia byte a byte (não recomendado para CJK):
[0] 72 H
[1] 101 e
[2] 108 l
[3] 108 l
[4] 111 o
[5] 44 ,
[6] 228 ä
[7] 184 ¸
[8] 150 \x96
[9] 228 ä
[10] 150 \x96
[11] 175 ¯
Travessia rune a rune (trata corretamente CJK):
[0] U+0048 'H'
[1] U+0065 'e'
[2] U+006C 'l'
[3] U+006C 'l'
[4] U+006F 'o'
[5] U+002C ','
[6] U+4E16 '世'
[7] U+754C '界'
Pontos-Chave:
iotacomeça a partir de 0 e auto-incrementa em 1 por linha, sendo perfeito para definir constantes de enumeração.- Permissões bitwise são uma aplicação clássica de
iota: use|para combinar permissões e¶ verificar permissões. int(float64)trunca diretamente a parte decimal, não arredonda.len(string)retorna a contagem de bytes, não a contagem de caracteres. Caracteres CJK ocupam 3 bytes em UTF-8.- Use
rangepara iterar sobre strings para tratar corretamente caracteres multibyte (runes).
Exemplo 3: Aplicação Abrangente (Dificuldade ⭐⭐⭐)
Cenário: Simule um sistema simples de processamento de informações de registro de usuário, combinando variáveis, constantes, conversão de tipos e saída formatada.
package main
import (
"fmt"
"strings"
)
// ========== Constantes ==========
// Enum de gênero
type Gender int
const (
Unknown Gender = iota // 0: Desconhecido
Male // 1: Masculino
Female // 2: Feminino
)
func (g Gender) String() string {
return [...]string{"Desconhecido", "Masculino", "Feminino"}[g]
}
// Níveis de associação e descontos correspondentes
const (
LevelBronze = 1
LevelSilver = 2
LevelGold = 3
LevelPlatinum = 4
)
// Usar iota para gerar percentuais de desconto
const (
_ = iota // Pular 0
DiscountBronze = 95 // 5% de desconto
DiscountSilver = 90 // 10% de desconto
DiscountGold = 85 // 15% de desconto
DiscountPlatinum = 80 // 20% de desconto
)
// ========== Struct do Usuário (Prévia, detalhada em lições posteriores) ==========
type User struct {
Nome string
Idade int
Gender Gender
Level int
Saldo float64
}
// ========== Lógica Central ==========
func main() {
// Dados simulados de usuários
users := []User{
{Nome: "Li Ming", Idade: 25, Gender: Male, Level: LevelGold, Saldo: 1580.50},
{Nome: "Wang Fang", Idade: 30, Gender: Female, Level: LevelPlatinum, Saldo: 3200.00},
{Nome: "Zhang Wei", Idade: 17, Gender: Male, Level: LevelBronze, Saldo: 200.00},
{Nome: "Zhao Min", Idade: 22, Gender: Female, Level: LevelSilver, Saldo: 800.75},
}
fmt.Println("╔══════════════════════════════════════════════════════════╗")
fmt.Println("║ Sistema de Registro de Usuários ║")
fmt.Println("╚══════════════════════════════════════════════════════════╝")
fmt.Println()
// Variáveis de estatísticas
var totalIdade int
var totalSaldo float64
var contagemMasculino, contagemFeminino int
var contagemAdulto int
for _, u := range users {
// Obter desconto
desconto := getDiscount(u.Level)
valorDesconto := u.Saldo * float64(100-desconto) / 100.0
// Formatar saída de informações do usuário
tagIdade := ""
if u.Idade >= 18 {
tagIdade = "✅ Adulto"
contagemAdulto++
} else {
tagIdade = "❌ Menor"
}
fmt.Printf("👤 %-8s | Gênero: %-6s | Idade: %d (%s) | Nível: Lv.%d | Saldo: $%.2f\n",
u.Nome, u.Gender, u.Idade, tagIdade, u.Level, u.Saldo)
fmt.Printf(" 💰 %d%% desconto, economia $%.2f\n", desconto, valorDesconto)
// Estatísticas
totalIdade += u.Idade
totalSaldo += u.Saldo
switch u.Gender {
case Male:
contagemMasculino++
case Female:
contagemFeminino++
}
fmt.Println(strings.Repeat("-", 60))
}
// Imprimir estatísticas
mediaIdade := float64(totalIdade) / float64(len(users))
fmt.Println()
fmt.Println("📊 Estatísticas:")
fmt.Printf(" Total de usuários: %d\n", len(users))
fmt.Printf(" Masculino: %d | Feminino: %d\n", contagemMasculino, contagemFeminino)
fmt.Printf(" Adultos: %d | Menores: %d\n", contagemAdulto, len(users)-contagemAdulto)
fmt.Printf(" Idade média: %.1f anos\n", mediaIdade)
fmt.Printf(" Saldo total: $%.2f\n", totalSaldo)
fmt.Printf(" Saldo médio: $%.2f\n", totalSaldo/float64(len(users)))
// Demonstrar conversão de tipos e formatação
fmt.Println()
fmt.Println("🔧 Demonstração de Conversão de Tipos:")
demoTypeConversion()
}
// getDiscount retorna o desconto com base no nível de associação
func getDiscount(level int) int {
switch level {
case LevelBronze:
return DiscountBronze
case LevelSilver:
return DiscountSilver
case LevelGold:
return DiscountGold
case LevelPlatinum:
return DiscountPlatinum
default:
return 100 // Sem desconto
}
}
// demoTypeConversion demonstra vários cenários de conversão de tipos
func demoTypeConversion() {
// 1. Conversão de tipo numérico
var pi float64 = 3.14159
var intPi int = int(pi) // Trunca, não arredonda
fmt.Printf(" float64 → int: %.5f → %d\n", pi, intPi)
// 2. Número → string (dois métodos comparados)
var num int = 2024
way1 := string(rune(num)) // Caractere Unicode → não é o que você quer
way2 := fmt.Sprintf("%d", num) // String decimal → "2024"
way3 := fmt.Sprintf("%x", num) // String hexadecimal → "7e8"
fmt.Printf(" int → string (rune): %q\n", way1)
fmt.Printf(" int → string (%%d): %q\n", way2)
fmt.Printf(" int → string (%%x): %q\n", way3)
// 3. String → número (usando fmt.Sscanf)
var parsed int
_, err := fmt.Sscanf("12345", "%d", &parsed)
if err == nil {
fmt.Printf(" string → int (Sscanf): %d\n", parsed)
}
// 4. bool → string
b := true
boolStr := fmt.Sprintf("%t", b)
fmt.Printf(" bool → string: %t → %q\n", b, boolStr)
// 5. Diferença entre rune e byte
var r rune = '中'
var b2 byte = 'A'
fmt.Printf(" rune '中': valor=%d, hex=%U, %d bytes (UTF-8)\n", r, r, len(string(r)))
fmt.Printf(" byte 'A': valor=%d, hex=%U, 1 byte\n", b2, b2)
}
Saída:
╔══════════════════════════════════════════════════════════╗
║ Sistema de Registro de Usuários ║
╚══════════════════════════════════════════════════════════╝
👤 Li Ming | Gênero: Male | Idade: 25 (✅ Adulto) | Nível: Lv.3 | Saldo: $1580.50
💰 15% desconto, economia $237.08
------------------------------------------------------------
👤 Wang Fang | Gênero: Female | Idade: 30 (✅ Adulto) | Nível: Lv.4 | Saldo: $3200.00
💰 20% desconto, economia $640.00
------------------------------------------------------------
👤 Zhang Wei | Gênero: Male | Idade: 17 (❌ Menor) | Nível: Lv.1 | Saldo: $200.00
💰 5% desconto, economia $10.00
------------------------------------------------------------
👤 Zhao Min | Gênero: Female | Idade: 22 (✅ Adulto) | Nível: Lv.2 | Saldo: $800.75
💰 10% desconto, economia $80.08
------------------------------------------------------------
📊 Estatísticas:
Total de usuários: 4
Masculino: 2 | Feminino: 2
Adultos: 3 | Menores: 1
Idade média: 23.5 anos
Saldo total: $5781.25
Saldo médio: $1445.31
🔧 Demonstração de Conversão de Tipos:
float64 → int: 3.14159 → 3
int → string (rune): "\u07e8"
int → string (%d): "2024"
int → string (%x): "7e8"
string → int (Sscanf): 12345
bool → string: true → "true"
rune '中': valor=20013, hex=U+4E16, 3 bytes (UTF-8)
byte 'A': valor=65, hex=U+0041, 1 byte
Pontos-Chave:
- Blocos de constantes com
iotapodem definir elegantemente enums e valores incrementais. - A conversão de tipos deve ser explícita; Go não converterá automaticamente para você.
string(int)efmt.Sprintf("%d", int)têm efeitos completamente diferentes — o primeiro produz um caractere Unicode, o segundo uma string numérica.runeé para tratar caracteres Unicode;byteé para tratar dados de byte único.%qformata strings com aspas e escapa caracteres especiais, muito útil para depuração.
3. Casos de Uso Comuns
Caso 1: Gerenciamento de Configuração
package main
import "fmt"
// Constantes de configuração da aplicação (determinadas em tempo de compilação, imutáveis)
const (
AppName = "GoWeb"
Version = "1.0.0"
MaxRetries = 3
DefaultTimeout = 30 // segundos
)
// Enum de ambiente
type Env int
const (
Dev Env = iota // Desenvolvimento
Staging // Homologação
Prod // Produção
)
func (e Env) String() string {
return [...]string{"Dev", "Staging", "Prod"}[e]
}
func main() {
// Variáveis de runtime
currentEnv := Prod
dbHost := "192.168.1.100"
dbPort := 3306
debug := currentEnv == Dev
fmt.Printf("App: %s v%s\n", AppName, Version)
fmt.Printf("Ambiente: %s\n", currentEnv)
fmt.Printf("Banco de dados: %s:%d\n", dbHost, dbPort)
fmt.Printf("Modo debug: %t\n", debug)
fmt.Printf("Máximo de tentativas: %d, Timeout: %d segundos\n", MaxRetries, DefaultTimeout)
}
Caso 2: Formatação de Dados e Relatórios
package main
import "fmt"
func main() {
// Dados simulados de notas de estudantes
type Student struct {
Name string
Score float64
Grade string
}
students := []Student{
{"Alice", 92.5, ""},
{"Bob", 87.0, ""},
{"Charlie", 76.5, ""},
{"Diana", 95.0, ""},
{"Eve", 63.0, ""},
}
// Atribuir notas automaticamente com base nas pontuações
for i := range students {
switch {
case students[i].Score >= 90:
students[i].Grade = "A (Excelente)"
case students[i].Score >= 80:
students[i].Grade = "B (Bom)"
case students[i].Score >= 70:
students[i].Grade = "C (Médio)"
case students[i].Score >= 60:
students[i].Grade = "D (Aprovado)"
default:
students[i].Grade = "F (Reprovado)"
}
}
// Imprimir relatório de notas
fmt.Println("┌─────────┬────────┬────────────┐")
fmt.Println("│ Nome │ Nota │ Grau │")
fmt.Println("├─────────┼────────┼────────────┤")
var total float64
for _, s := range students {
fmt.Printf("│ %-7s │ %6.1f │ %-10s │\n", s.Name, s.Score, s.Grade)
total += s.Score
}
fmt.Println("├─────────┼────────┼────────────┤")
fmt.Printf("│ Média │ %6.1f │ │\n", total/float64(len(students)))
fmt.Println("└─────────┴────────┴────────────┘")
}
❓ Perguntas Frequentes
P1: O que devo usar, var ou :=? (Confusão conceitual)
R: Siga este princípio simples:
| Cenário | Recomendado | Razão |
|---|---|---|
| Declarar e atribuir dentro de função | := |
Mais conciso, convenção da comunidade Go |
| Declarar sem atribuição dentro de função | var |
:= requer atribuição |
| Variável de nível de pacote | var |
:= não pode ser usado fora de funções |
| Precisar de especificação explícita de tipo | var |
Evitar inferência de tipo inesperada |
func exemplo() {
// ✅ Recomendado: usar := dentro de funções
nome := "Go"
contagem := 0
// ✅ Deve usar var: declarar sem atribuição
var resultado string
if algumaCondicao {
resultado = "sim"
} else {
resultado = "não"
}
// ✅ Deve usar var: precisa do tipo exato
var b byte = 255 // := inferiria como int
}
P2: Por que string(65) não é igual a "65"? (Armadilha comum)
R: string(int) trata o inteiro como um ponto de código Unicode, não como representação textual do número:
// ❌ Suposição errada
s1 := string(65) // Esperado "65", na verdade obteve "A" (Unicode U+0041)
// ✅ Abordagem correta
s2 := fmt.Sprintf("%d", 65) // "65"
s3 := strconv.Itoa(65) // "65" (requer import "strconv")
// Uso real de string(rune): ponto de código Unicode → caractere
ch := string(rune(20013)) // "中" (U+4E16)
P3: Por que len("Hello,世界") não é igual a 8? (Armadilha comum)
R: len() retorna a contagem de bytes, não a contagem de caracteres. Strings Go usam codificação UTF-8 por padrão, e caracteres CJK ocupam 3 bytes cada:
s := "Hello,世界"
fmt.Println(len(s)) // 12 (5 + 1 + 3×2 = 12 bytes)
fmt.Println(utf8.RuneCountInString(s)) // 8 (5 + 1 + 2 = 8 caracteres)
// Maneira correta de contar caracteres
contagem := 0
for range s {
contagem++
}
fmt.Println(contagem) // 8
P4: Como trocar duas variáveis rapidamente? (Dica prática)
R: Go suporta atribuição múltipla, uma linha de código resolve:
a, b := 10, 20
a, b = b, a // Trocar: a=20, b=10
// Você também pode ignorar um valor desta forma
_, err := algumaFunção() // Use _ para ignorar valor de retorno indesejado
📖 Resumo
- Declaração de variáveis tem dois métodos:
var(universal, pode ser fora de funções) e:=(conciso, apenas dentro de funções). - Go tem tipos básicos variados:
int/uint/float64/bool/string/byte/rune. - O mecanismo de valor zero garante que variáveis sempre tenham um valor definido após a declaração: números
0, booleanofalse, string"", ponteironil. constdeclara constantes;iotaauto-incrementa a partir de 0 em blocosconst, adequado para definir enums.- Go não suporta conversão implícita de tipos; tipos diferentes devem ser convertidos explicitamente, e a conversão pode perder precisão.
- O pacote
fmté uma ferramenta poderosa para saída formatada:Printlnpara imprimir,Printfpara formatar,Sprintfpara gerar strings. len(string)retorna a contagem de bytes; userangepara iterar strings para tratar corretamente caracteres multibyte.string(int)trata inteiros como pontos de código Unicode, não como conversão de número para texto; usefmt.Sprintfpara número para texto.
📝 Exercícios
Exercício 1 (⭐): Variáveis e Valores Zero
Declare as seguintes variáveis e imprima seus valores zero:
- Uma variável
intcontagem - Uma variável
float64preco - Uma variável
boolativo - Uma variável
stringmensagem
Saída esperada:
contagem: 0
preco: 0
ativo: false
mensagem: ""
Exercício 2 (⭐⭐): Enum iota e Conversão de Tipos
Defina um tipo Color (subjacente int), use iota para definir três cores: Red=0, Green=1, Blue=2. Implemente um método String() para Color. Então:
- Declare uma variável
Colordefinida comoGreen, imprima seu nome e valor. - Converta o valor
float643.14159paraint, imprima o resultado (deve ser3). - Converta o número
2025para string"2025", imprima o resultado.
Exercício 3 (⭐⭐⭐): Ferramenta de Conversão de Temperatura
Escreva um programa que faça o seguinte:
- Defina uma constante
AbsoluteZeroC = -273.15(zero absoluto em Celsius). - Declare um conjunto de temperaturas em Celsius:
-40, 0, 37, 100. - Itere pelo array de temperaturas, convertendo cada temperatura Celsius para Fahrenheit (fórmula:
F = C × 9/5 + 32). - Formate a saída como uma tabela, com requisitos:
- Temperaturas Celsius e Fahrenheit arredondadas para 1 casa decimal
- Indique se a temperatura está abaixo do zero absoluto (fisicamente impossível)
- Alinhe larguras de colunas
Saída esperada:
┌─────────┬─────────┬────────────┐
│ Celsius │Fahrenheit│ Status │
├─────────┼─────────┼────────────┤
│ -40.0 │ -40.0 │ Válido │
│ 0.0 │ 32.0 │ Válido │
│ 37.0 │ 98.6 │ Válido │
│ 100.0 │ 212.0 │ Válido │
└─────────┴─────────┴────────────┘
Dica: Use const, var (array/slice), loop for, formatação fmt.Printf, conversão de tipos (int ↔ float64).



