Seu primeiro programa: Hello World e o compilador
1. Configurando o ambiente para o primeiro programa
Antes de escrever qualquer linha de código em Go, é essencial configurar o ambiente corretamente. A primeira decisão importante é sobre a estrutura de diretórios.
Historicamente, Go utilizava o GOPATH, um diretório único onde todos os projetos e suas dependências residiam. A estrutura era rígida: $GOPATH/src/github.com/usuario/projeto. Hoje, o ecossistema evoluiu para o sistema de módulos (introduzido no Go 1.11), que elimina a necessidade do GOPATH para projetos individuais.
Para iniciar, crie uma pasta para seu projeto e acesse-a:
mkdir hello-world
cd hello-world
Agora, inicialize um módulo Go:
go mod init hello-world
Esse comando cria o arquivo go.mod, que define o nome do módulo e gerencia as dependências. O nome do módulo (aqui hello-world) será usado internamente para importar pacotes.
Quanto ao editor, qualquer IDE moderna funciona bem com Go. Visual Studio Code com a extensão oficial da Go é a escolha mais popular, oferecendo autocomplete, linting e integração com ferramentas essenciais como:
go fmt— formata automaticamente o código seguindo o padrão da linguagemgo vet— analisa o código em busca de suspeitas de bugs
2. Escrevendo o clássico Hello World
Com o ambiente pronto, crie o arquivo main.go com o seguinte conteúdo:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
Vamos analisar cada parte desse código:
-
package main: Todo arquivo.gopertence a um pacote. O pacotemainé especial — ele define que este código pode ser executado como um programa independente. Sem essa declaração, o compilador não geraria um executável. -
import "fmt": O pacotefmt(format) fornece funções para entrada e saída formatada. Aqui usamosPrintlnpara exibir texto no terminal. -
func main(): Esta é a função de entrada obrigatória de todo programa Go. A execução sempre começa aqui. Note quemainnão recebe parâmetros e não retorna valor (diferente de C, por exemplo). -
fmt.Println("Hello, World!"): A funçãoPrintlnimprime o argumento seguido de uma quebra de linha. As aspas duplas delimitam a string literal.
3. Entendendo o fluxo do compilador Go
Go é uma linguagem compilada, não interpretada. Diferente de Python ou JavaScript, que dependem de um interpretador em tempo de execução, Go traduz seu código diretamente para instruções de máquina nativas do sistema operacional alvo.
O compilador Go (go build) realiza várias etapas:
- Análise léxica e sintática: Verifica se o código segue a gramática da linguagem
- Verificação de tipos: Garante que operações entre tipos incompatíveis não ocorram
- Otimizações: Elimina código morto, inlineia funções pequenas, otimiza loops
- Geração de código nativo: Produz binário específico para a arquitetura (amd64, arm64) e sistema operacional (Linux, Windows, macOS)
Uma característica marcante é que o compilador Go é extremamente rápido. Isso é alcançado por um design que simplifica a análise de dependências e evita otimizações agressivas que atrasariam a compilação.
4. Compilando o programa: passo a passo
Para compilar seu programa, execute:
go build
Isso gera um binário executável com o nome do diretório (no nosso caso, hello-world). Você pode especificar um nome diferente:
go build -o meu-programa
O binário gerado é estaticamente vinculado — ele contém tudo que precisa para executar, incluindo o runtime Go. Não depende de bibliotecas externas no sistema. Isso resulta em binários maiores (cerca de 1-2 MB para um Hello World), mas extremamente portáteis.
Execute o binário compilado:
./hello-world
Saída:
Hello, World!
Para compilar para outro sistema operacional, use variáveis de ambiente:
GOOS=windows GOARCH=amd64 go build -o hello.exe
GOOS=linux GOARCH=arm64 go build
Isso permite criar binários para diferentes plataformas sem modificar o código.
5. Executando sem compilar: o comando go run
O comando go run combina compilação e execução em um único passo:
go run main.go
Saída:
Hello, World!
Internamente, go run compila o código em um diretório temporário, executa o binário e o descarta. Isso é útil durante o desenvolvimento para testes rápidos.
Diferenças práticas:
go build |
go run |
|---|---|
| Gera binário permanente | Compila e executa, depois descarta |
| Ideal para distribuição | Ideal para desenvolvimento |
| Único comando para executar depois | Precisa recompilar toda vez |
| Binário pode ser copiado para outras máquinas | Não gera artefato reutilizável |
Para projetos reais, use go run durante o desenvolvimento e go build quando precisar distribuir o programa.
6. Explorando o código compilado
Vamos examinar o binário gerado:
file hello-world
ls -lh hello-world
No Linux, a saída típica é:
hello-world: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
-rwxr-xr-x 1 user user 1.8M Mar 15 10:30 hello-world
Observe que o binário é statically linked (vinculado estaticamente). Diferente de programas em C que geralmente dependem de bibliotecas dinâmicas (.so ou .dll), um binário Go contém todo o runtime necessário.
Isso significa que você pode copiar o binário para qualquer máquina com o mesmo sistema operacional e arquitetura, e ele executará sem precisar instalar Go ou qualquer outra dependência. Não há máquina virtual (como a JVM do Java) — o runtime é embutido diretamente no executável.
7. Erros comuns no primeiro programa
Pacote main não declarado
package minhaapp
func main() {
fmt.Println("Hello")
}
Erro: runtime.main_main·f: function main is undeclared in the main package. O compilador espera que o pacote seja main para gerar um executável.
Função main ausente
package main
import "fmt"
func init() {
fmt.Println("Hello")
}
Erro: runtime.main_main·f: function main is undeclared in the main package. A função init existe e é executada automaticamente, mas não substitui a main.
Import não utilizado
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println("Hello")
}
Erro: imported and not used: "os". Go não permite imports não utilizados. Isso evita código morto e mantém as dependências limpas.
Espaços em branco e formatação
Go impõe um estilo de formatação único. Execute go fmt ./... no diretório do projeto para corrigir automaticamente indentação, espaçamento e alinhamento. Isso garante consistência em todo o ecossistema Go.
Com este primeiro programa, você já percorreu o ciclo completo: configurou o ambiente, escreveu código, compilou, executou e aprendeu a lidar com erros comuns. Esse conhecimento forma a base para explorar conceitos mais avançados da linguagem.
Referências
- Documentação oficial: Como escrever código Go — Guia oficial sobre organização de código, módulos e o pacote main
- Documentação do comando
go build— Referência completa sobre flags e comportamento do compilador - Go by Example: Hello World — Exemplo prático e comentado do primeiro programa em Go
- Effective Go: Introduction — Boas práticas oficiais para escrever código Go idiomático
- Tutorial: Get started with Go — Tutorial oficial passo a passo da instalação ao primeiro programa
- Understanding Go's Compiler — Artigo técnico sobre a arquitetura do compilador Go e suas otimizações