O que é Constant em Go?
Uma constant (constante) em Go é um valor imutável definido em tempo de compilação usando a palavra-chave const. Diferente de uma variável, uma constante não pode ser modificada após sua declaração — qualquer tentativa de alteração resulta em erro de compilação.
Constantes são fundamentais na linguagem Go porque garantem segurança e previsibilidade no código. Elas permitem que o compilador otimize o programa, substituindo referências a constantes diretamente pelos seus valores durante a compilação, eliminando qualquer overhead em tempo de execução.
Em Go, constantes podem representar valores numéricos (inteiros, ponto flutuante, complexos), strings, booleanos e runes. Diferente de muitas outras linguagens, Go possui um sistema de constantes extremamente poderoso, com suporte a constantes não tipadas que mantêm precisão arbitrária durante a avaliação de expressões em tempo de compilação.
Declarando constantes em Go
Constante simples
A forma mais básica de declarar uma constante usa a palavra-chave const:
const pi = 3.14159265358979323846
const saudacao = "Olá, mundo!"
const ativo = true
Constante tipada vs não tipada
Go diferencia entre constantes tipadas e não tipadas, e essa distinção é uma das características mais elegantes da linguagem:
// Constante não tipada — flexível, pode ser usada em diferentes contextos
const valor = 42
// Constante tipada — restrita ao tipo declarado
const limite int64 = 1000000
func exemplo() {
var x int32 = valor // OK: constante não tipada se adapta
var y float64 = valor // OK: mesma constante funciona como float64
// var z int32 = limite // ERRO: limite é int64, não int32
_ = x
_ = y
}
Constantes não tipadas são chamadas de “ideal constants” na especificação do Go. Elas têm precisão arbitrária e só recebem um tipo concreto quando são atribuídas a uma variável ou usadas em um contexto que exige um tipo específico.
Bloco de constantes
Quando você precisa declarar múltiplas constantes relacionadas, use um bloco const:
const (
appNome = "Golang Brasil"
appVersao = "2.1.0"
appPorta = 8080
appTimeout = 30
)
Essa abordagem organiza o código e deixa claro que as constantes pertencem ao mesmo grupo lógico — algo muito comum em packages bem estruturados.
O poder do iota
Enumerações com iota
O iota é o mecanismo de Go para criar sequências enumeradas automaticamente dentro de blocos const. Ele começa em 0 e é incrementado a cada linha:
const (
Domingo = iota // 0
Segunda // 1
Terca // 2
Quarta // 3
Quinta // 4
Sexta // 5
Sabado // 6
)
iota com expressões
O verdadeiro poder do iota aparece quando combinado com expressões:
// Unidades de armazenamento usando bit shifting
const (
_ = iota // descarta o valor 0
KB = 1 << (10 * iota) // 1 << 10 = 1024
MB // 1 << 20 = 1048576
GB // 1 << 30 = 1073741824
TB // 1 << 40
PB // 1 << 50
)
func main() {
tamanhoArquivo := 2.5 * float64(GB)
fmt.Printf("Tamanho: %.2f GB\n", tamanhoArquivo/float64(GB))
}
iota com bitmask (flags)
Um padrão extremamente útil para flags e permissões:
const (
Leitura = 1 << iota // 1 (001)
Escrita // 2 (010)
Execucao // 4 (100)
)
func temPermissao(permissoes, flag int) bool {
return permissoes&flag != 0
}
func main() {
minhasPermissoes := Leitura | Escrita // 3 (011)
fmt.Println(temPermissao(minhasPermissoes, Leitura)) // true
fmt.Println(temPermissao(minhasPermissoes, Execucao)) // false
}
Esse padrão é amplamente utilizado na standard library, por exemplo em os.FileMode, e é essencial quando você trabalha com interfaces que definem comportamentos baseados em flags.
iota reinicia em cada bloco const
Um detalhe importante: iota reinicia em 0 a cada novo bloco const:
const (
A = iota // 0
B // 1
)
const (
C = iota // 0 — reiniciou!
D // 1
)
Constantes e tipos customizados
Um padrão idiomático em Go é combinar constantes com tipos customizados para criar enumerações seguras:
type Status int
const (
Pendente Status = iota
Aprovado
Rejeitado
Cancelado
)
func (s Status) String() string {
nomes := [...]string{"Pendente", "Aprovado", "Rejeitado", "Cancelado"}
if s < Pendente || s > Cancelado {
return "Desconhecido"
}
return nomes[s]
}
func processarPedido(status Status) {
switch status {
case Pendente:
fmt.Println("Aguardando aprovação...")
case Aprovado:
fmt.Println("Pedido aprovado!")
case Rejeitado:
fmt.Println("Pedido rejeitado.")
case Cancelado:
fmt.Println("Pedido cancelado.")
}
}
Essa abordagem é preferível a usar int ou string diretamente porque o compilador pode verificar atribuições inválidas. É o padrão recomendado em projetos profissionais e em APIs REST.
Precisão de constantes numéricas
Uma das características mais impressionantes do sistema de constantes em Go é a precisão arbitrária para constantes não tipadas:
const (
// Precisão muito maior que float64
precisao = 3.14159265358979323846264338327950288419716939937510
// Aritimética com precisão total em tempo de compilação
resultado = precisao * precisao // calculado com precisão completa
)
func main() {
// Só perde precisão quando atribuído a uma variável
var f float64 = resultado
fmt.Println(f) // arredondado para precisão de float64
}
Isso significa que expressões com constantes são avaliadas com precisão arbitrária pelo compilador, e o arredondamento só acontece quando o valor é atribuído a uma variável com tipo concreto.
Constantes vs variáveis: quando usar cada uma
A regra é simples: use constantes sempre que o valor não precisa mudar durante a execução do programa.
// Use const para valores fixos
const (
maxTentativas = 3
timeoutPadrao = 30 // segundos
versaoAPI = "v2"
)
// Use var para valores que mudam
var (
contadorRequests int
ultimoErro error
conexaoAtiva bool
)
Benefícios de usar constantes:
- Segurança: o compilador impede modificações acidentais
- Performance: valores substituídos diretamente no código compilado
- Documentação: indica claramente a intenção de imutabilidade
- Otimização: permite ao compilador fazer inlining automático
Para entender melhor o uso de variáveis e quando cada abordagem é mais adequada, compare os exemplos acima e considere o contexto do seu projeto.
O que NÃO pode ser constante em Go
Nem tudo pode ser declarado como constante em Go. Apenas tipos básicos são permitidos:
// Funciona: tipos básicos
const nome = "Go"
const idade = 15
const ativo = true
// NÃO funciona: tipos compostos
// const lista = []int{1, 2, 3} // ERRO
// const mapa = map[string]int{} // ERRO
// const pessoa = Pessoa{Nome: "Ana"} // ERRO
Se você precisa de valores imutáveis com tipos compostos, o padrão é usar variáveis de package com nomes que indicam imutabilidade, ou encapsular em funcs que retornam novos valores a cada chamada.
Constantes em projetos reais
Configuração de aplicação
package config
const (
DefaultPort = 8080
DefaultHost = "localhost"
MaxConnections = 100
ReadTimeout = 15 // segundos
WriteTimeout = 15 // segundos
)
Códigos de erro
type ErrCode int
const (
ErrNotFound ErrCode = 404
ErrUnauthorized ErrCode = 401
ErrInternalError ErrCode = 500
ErrBadRequest ErrCode = 400
)
Mensagens e templates
const (
MsgBoasVindas = "Bem-vindo ao sistema"
MsgErroLogin = "Credenciais inválidas"
MsgSucesso = "Operação realizada com sucesso"
)
Esses padrões são essenciais ao construir microsserviços e aplicações backend robustas com tratamento adequado de erros.
Boas práticas com constantes
- Use nomes descritivos:
maxRetriesé melhor quemr - Agrupe constantes relacionadas em blocos
const - Prefira constantes não tipadas quando a flexibilidade é necessária
- Use iota para enumerações — mais legível e menos propenso a erros
- Exporte apenas o necessário: constantes internas devem ser minúsculas
- Documente valores não óbvios: explique por que o valor é aquele
Para mais fundamentos da linguagem, explore o glossário completo e os tutoriais de Go para iniciantes.
Perguntas frequentes (FAQ)
Qual a diferença entre const e var em Go?
const define valores imutáveis conhecidos em tempo de compilação, enquanto var define variáveis que podem mudar durante a execução. Constantes são substituídas diretamente no código compilado, eliminando overhead de acesso à memória. Use const sempre que o valor não precisar mudar — garante segurança e melhor performance.
Como funciona o iota em Go?
O iota é um identificador especial usado dentro de blocos const que começa em 0 e incrementa automaticamente a cada nova constante no bloco. Pode ser combinado com expressões (como 1 << iota para bitmasks) e reinicia em 0 em cada novo bloco const. É a forma idiomática de criar enumerações em Go.
Posso criar constantes com structs ou slices em Go?
Não. Em Go, apenas tipos básicos podem ser constantes: números (inteiros, float, complexos), strings, booleanos e runes. Tipos compostos como structs, slices, maps e arrays não podem ser constantes. Para valores compostos imutáveis, use variáveis de package não exportadas ou funções construtoras.
Quando usar constantes tipadas vs não tipadas?
Use constantes não tipadas (sem tipo explícito) quando quiser flexibilidade — elas se adaptam ao contexto de uso. Use constantes tipadas quando quiser restringir o uso a um tipo específico, como em enumerações com type Status int. Constantes não tipadas mantêm precisão arbitrária durante a compilação, o que é útil para cálculos numéricos precisos.