Valores Zero e Inicialização
Todo tipo Go tem um valor zero: o valor que uma variável contém antes de você atribuir qualquer coisa.
Busque em todas as páginas da documentação
Todo tipo Go tem um valor zero: o valor que uma variável contém antes de você atribuir qualquer coisa.
Projetar com valores zero em mente leva a APIs mais simples e menos verificações de nil.
Declarar com var ou alocar com new/make sem dados extras produz o valor zero do tipo.
Tipos numéricos são 0, bool é false, strings são "", e tipos de referência (ponteiros, slices, mapas, canais, funções, interfaces) são nil.
Go idiomático frequentemente torna o valor zero útil, para que os chamadores possam inicializar uma struct com zero e usá-la imediatamente.
Cartão de receita de referência rápida - pronto para copiar e colar.
package main
import "fmt"
type Config struct {
Host string
Port int
}
func main() {
var cfg Config // zero: Host "", Port 0
cfg.Host = "localhost"
cfg.Port = 8080
nums := make([]int, 0, 8) // slice vazio, não-nil
fmt.Println(cfg, nums == nil)
}Quando usar isso:
sync.Mutex, muitas structs de configuração).make para slices, mapas e canais quando precisar de um valor pronto para uso e não nil.T{...} quando os padrões não forem suficientes.package main
import (
"bytes"
"fmt"
)
type Buffer struct {
buf bytes.Buffer
ok bool
}
func (b *Buffer) WriteString(s string) {
if !b.ok {
b.buf = *bytes.NewBuffer(nil)
b.ok = true
}
b.buf.WriteString(s)
}
func (b Buffer) String() string {
if !b.ok {
return ""
}
return b.buf.String()
}
func main() {
var b Buffer // valor zero utilizável: String() retorna ""
b.WriteString("hello")
fmt.Println(b.String())
m := make(map[string]int)
m["a"] = 1
var sl []int // slice nil
sl = append(sl, 2)
fmt.Println(m, sl)
}O que isso demonstra:
make(map[K]V) retorna um mapa vazio, não nil, pronto para atribuição.nil funcionam com append e len/cap retornam 0.bytes.Buffer mudaria o comportamento do valor zero - projete os campos deliberadamente.var x T aloca armazenamento e define os bits como zero para o tipo T.new(T) retorna *T apontando para armazenamento inicializado com zero (raramente necessário em comparação com &T{}).make aplica-se apenas a slices, mapas e canais; ele aloca a estrutura interna.T{v} ou &T{v} definem campos explicitamente, deixando outros em zero.| Tipo | Valor zero | Utilizável sem inicialização? |
|---|---|---|
int, float, complex | 0 | Sim |
bool | false | Sim |
string | "" | Sim |
pointer, func, interface | nil | Apenas após verificações de nil |
slice | nil | Sim para len, append, range |
map | nil | Não para atribuição - causa pânico |
channel | nil | Não para envio/recebimento - bloqueia ou causa pânico |
struct | cada campo zero | Depende dos tipos de campo |
| Padrão | Exemplo | Quando |
|---|---|---|
| Zero + definir campos | var c Config; c.Port = 8080 | Poucos campos, padrões seguros |
| Literal composto | Config{Host: "x"} | Valores conhecidos na criação |
make | make([]int, 0, n) | Pré-alocar capacidade |
| Função construtora | NewServer(cfg) | Validação ou invariantes necessários |
import "sync"
// O valor zero de Mutex é um mutex destravado - pronto para uso
var mu sync.Mutex
mu.Lock()
// Prefira &T{} em vez de new(T) para structs quando você pode adicionar campos mais tarde
srv := &Server{}var m map[string]int; m["k"] = 1 causa pânico. Correção: m = make(map[string]int) ou um literal de mapa antes da atribuição.select ou causa deadlock. Correção: make(chan T) ou proteja com verificação de nil.var p *T; var i interface{} = p faz i != nil ser verdadeiro enquanto p == nil. Correção: retorne tipos concretos ou verifique o nil tipado explicitamente.int pode ser inválido para APIs de rede. Correção: use ponteiros *int ou net.JoinHostPort com validação.var s []int e s := []int{} diferem para JSON (null vs []). Correção: escolha intencionalmente para semântica de serialização.new - new(T) retorna *T para zeros; muitos guias de estilo preferem &T{} para structs. Correção: use literais compostos para clareza.| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Struct de valor zero | Mutexes, configurações simples | Campos necessários não têm um padrão sensato |
make + append | Construindo slices dinamicamente | Arrays pequenos fixos são suficientes |
Campos ponteiro *int | Distinguir não definido de zero | Todos os campos se tornariam ponteiros (ruído) |
| Builder/construtor | Validação complexa | Structs simples com 2-3 campos |
Cada campo é definido para seu próprio valor zero recursivamente.
Para struct{ A int; B string }, isso é 0 e "".
Ambos têm len 0 e funcionam com append.
Eles diferem para == nil, codificação JSON e algumas APIs que tratam nil especialmente.
Use make quando precisar de um mapa, canal não nil, ou um slice com len/cap específicos.
var s []int é bom quando você apenas usará append.
new(T) retorna um ponteiro para armazenamento zerado.
A análise de escape decide pilha vs heap; new não força a alocação na heap por si só.
Structs são comparáveis apenas se todos os campos forem comparáveis.
Slices, mapas e funções tornam as structs não comparáveis.
Um valor de interface nil não tem tipo dinâmico nem valor.
Um ponteiro nil tipado atribuído a uma interface não é igual a uma interface nil.
var a [3]int são três zeros na pilha ou na struct.
var s []int é um cabeçalho nil sem array de suporte até make ou append.
Apenas quando invariantes são necessários (nome não vazio, porta positiva).
Muitos tipos da biblioteca padrão (bytes.Buffer, sync.Mutex) são projetados para uso com valor zero.
O zero de time.Time é 1º de janeiro de 1 d.C. UTC - raramente um sentinela útil.
Use ponteiros ou verificações time.Time.IsZero().
type Outer struct{ Inner Inner }
o := Outer{Inner: Inner{Field: 1}}Campos aninhados não mencionados permanecem zero dentro de Inner.
A atribuição copia o cabeçalho; o armazenamento de suporte é compartilhado.
Inicialize uma vez e passe com cuidado para evitar compartilhamento não intencional.
O Go zera alocações por segurança em muitos caminhos, mas não confie nisso para segredos criptográficos.
Sobrescreva buffers sensíveis explicitamente quando necessário.
var vs := no momento da declaraçãoVersões Stack: Esta página foi escrita para Go 1.26.x (GC padrão Green Tea, go fix modernizers - verifique o patch na compilação), chi (última versão - verifique na compilação), gin (última versão - verifique na compilação), echo (última versão - verifique na compilação), google.golang.org/grpc (última versão - verifique na compilação), sigs.k8s.io/controller-runtime (última versão - verifique na compilação), kubebuilder (última versão - verifique na compilação), tinygo (última versão - verifique os alvos de placa na compilação), wazero (última versão - verifique na compilação) e golangci-lint (última versão - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026