惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
Tailwind CSS Blog
J
Java Code Geeks
Microsoft Azure Blog
Microsoft Azure Blog
GbyAI
GbyAI
爱范儿
爱范儿
量子位
Martin Fowler
Martin Fowler
V
V2EX
博客园 - 三生石上(FineUI控件)
I
InfoQ
MongoDB | Blog
MongoDB | Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
N
Netflix TechBlog - Medium
D
DataBreaches.Net
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Last Week in AI
Last Week in AI
U
Unit 42
Apple Machine Learning Research
Apple Machine Learning Research
H
Help Net Security
T
The Blog of Author Tim Ferriss
Hugging Face - Blog
Hugging Face - Blog
美团技术团队
Engineering at Meta
Engineering at Meta

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Go do zero: var vs :=
Renato O da · 2026-05-03 · via DEV Community

Go tem duas formas de declarar variáveis: var e :=. Elas existem por motivos diferentes e têm regras diferentes. Saber quando cada uma se aplica evitamos erros bobos e código que não compila.

Sintaxe

var (forma longa)

var x int           // tipo explícito, recebe o zero value
var x int = 5       // tipo e valor
var x = 5           // valor com tipo inferido
var x, y = 1, 2     // múltiplas variáveis de uma vez

var (
    a int
    b string = "hi"
    c = 3.14
)

Enter fullscreen mode Exit fullscreen mode

O bloco var (...) é útil quando você quer agrupar declarações relacionadas, especialmente em nível de pacote.

:= (short variable declaration)

x := 5
a, b := 1, "hello"
ch := make(chan int)
v, ok := m[key]

Enter fullscreen mode Exit fullscreen mode

Pense no := como um atalho para var x = expr. Ele sempre infere o tipo a partir do valor à direita, e por isso o valor é obrigatório.

Regras principais

Aspecto var :=
Onde usar Pacote ou função Só dentro de função
Tipo explícito Opcional Não tem, sempre infere
Inicializador Opcional (usa o zero value) Obrigatório
Redeclaração Não Sim, com condições

A diferença mais importante na prática: := não funciona fora de uma função. Se você tentar usar no escopo de pacote, o compilador reclama.

Redeclaração com :=

Esse é um dos pontos que mais confunde quem está começando. O := permite reusar nomes já existentes, mas só se algumas condições forem atendidas:

  1. As variáveis já existentes precisam ter sido declaradas no mesmo bloco.
  2. O tipo precisa ser o mesmo.
  3. Pelo menos uma variável do lado esquerdo precisa ser nova.
  4. Nomes não-blank precisam ser únicos no lado esquerdo.

Um padrão comum com tratamento de erro:

field, offset := nextField(s, 0)
field, offset = nextField(s, offset)   // = atribui (ambas já existem)
field2, offset := nextField(s, offset) // := redeclara offset (field2 é nova)

Enter fullscreen mode Exit fullscreen mode

Note que na segunda linha usamos =, porque tudo já existe. Na terceira voltamos para := porque field2 é nova, e isso "carrega" a redeclaração de offset junto.

Já o exemplo abaixo não compila:

x, y, x := 1, 2, 3   // ilegal: x aparece duas vezes

Enter fullscreen mode Exit fullscreen mode

Quando usar cada um

Não existe uma regra absoluta, mas existem situações em que a escolha é praticamente automática.

Use var quando:

Está em nível de pacote (não tem escolha):

package main

var version = "1.0"   // := não funciona aqui

Enter fullscreen mode Exit fullscreen mode

Quer o zero value explicitamente:

var users []string   // nil slice, sem alocar nada

Enter fullscreen mode Exit fullscreen mode

Quer um tipo diferente do que seria inferido:

var port int32 = 8080   // com := seria int

Enter fullscreen mode Exit fullscreen mode

Está declarando várias variáveis de tipos diferentes em bloco:

var (
    name   string
    age    int
    active bool
)

Enter fullscreen mode Exit fullscreen mode

Use := quando:

Está dentro de uma função e tem um valor para inicializar.

Recebendo o retorno de uma função (esse é o uso mais idiomático):

data, err := os.ReadFile("config.yaml")

Enter fullscreen mode Exit fullscreen mode

Em if, for ou switch com escopo local:

if v, ok := m["k"]; ok {
    // Faça algo
}

Enter fullscreen mode Exit fullscreen mode

Aqui v e ok só existem dentro do if. Esse padrão é muito comum em Go e vale a pena memorizar.

Múltipla atribuição

Go permite atribuir várias variáveis de uma vez, onde temos algumas coisas úteis:

a, b := 1, 2
a, b = b, a            // swap sem variável temporária
x, _ := getXY()        // descarta o segundo retorno com _

Enter fullscreen mode Exit fullscreen mode

O _ é o blank identifier. Use ele quando precisa receber um valor que a função retorna mas não vai ser usado, isso evita que o compilador reclame de variável não usada.

Pegadinhas

nil sozinho não tem tipo

var n = nil      // erro: cannot infer type
var n *int = nil // ok
var n []int      // ok, zero value de slice já é nil

Enter fullscreen mode Exit fullscreen mode

O compilador não consegue adivinhar o tipo a partir de nil, porque nil é válido para vários tipos diferentes (ponteiros, slices, maps, channels, interfaces, funções). Você precisa indicar o tipo.

:= em escopo aninhado faz shadow

err := outer()
if true {
    err := inner()   // nova variável no bloco interno
    _ = err
}
// err aqui ainda é o da função outer

Enter fullscreen mode Exit fullscreen mode

A variável de fora continua intocada. Shadowing costume causar efeitos indesejáveis na execução. Então é necessário muito cuidado, ou evitar.

Variável declarada e não usada = erro de compilação

func f() {
    x := 10   // declared and not used
}

Enter fullscreen mode Exit fullscreen mode

Sempre que você declara um variável, Go obriga o uso. Variáveis não usadas costumam ser sinal de bug ou código morto.

Próximo post irei falar sobre Zero Values, até lá.