Criar seu Primeiro Projeto Zig
Parabéns por instalar o Zig! Zig é uma linguagem de programação de sistemas que combina performance de C com ferramentas modernas de desenvolvimento. Agora é hora de criar seu primeiro projeto. Este guia vai levá-lo do zero até um projeto funcional com compilação, execução, testes e uma estrutura profissional.
Certifique-se de que o Zig está instalado corretamente executando zig version. Se ainda não instalou, consulte o guia completo de instalação para sua plataforma.
Hello World: O Jeito Rápido
Antes de criar um projeto completo, vamos começar com o jeito mais rápido de executar código Zig.
Crie um arquivo hello.zig:
const std = @import("std");
pub fn main() void {
std.debug.print("Olá, mundo! Bem-vindo ao Zig!\n", .{});
}
Execute diretamente com:
zig run hello.zig
Saída:
Olá, mundo! Bem-vindo ao Zig!
O zig run compila e executa o programa em um único passo. Isso é ótimo para testes rápidos, mas para projetos reais, vamos usar o sistema de build do Zig.
Criando um Projeto com zig init
O Zig tem um comando integrado para criar a estrutura inicial de um projeto:
mkdir meu-projeto && cd meu-projeto
zig init
Isso cria a seguinte estrutura:
meu-projeto/
├── build.zig
├── build.zig.zon
└── src/
├── main.zig
└── root.zig
Entendendo os Arquivos
build.zig — Sistema de Build
O build.zig é o coração do sistema de build do Zig. Diferente de Makefiles ou CMakeLists, ele é escrito em Zig. Para um aprofundamento completo sobre todas as capacidades do sistema de build, incluindo dependências externas e steps customizados, consulte o guia completo do Zig Build System.
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "meu-projeto",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the application");
run_step.dependOn(&run_cmd.step);
const unit_tests = b.addTest(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
const run_unit_tests = b.addRunArtifact(unit_tests);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_unit_tests.step);
}
build.zig.zon — Dependências
O arquivo .zon (Zig Object Notation) define metadados e dependências do projeto:
.{
.name = "meu-projeto",
.version = "0.0.0",
.dependencies = .{},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
},
}
src/main.zig — Ponto de Entrada
const std = @import("std");
pub fn main() !void {
std.debug.print("All your {s} are belong to us.\n", .{"codebase"});
}
Compilar e Executar
Compilar o Projeto
zig build
O executável é criado em zig-out/bin/meu-projeto.
Executar o Projeto
zig build run
Ou execute o binário diretamente:
./zig-out/bin/meu-projeto
Compilar com Otimizações
# Debug (padrão) — com símbolos de debug, sem otimização
zig build
# ReleaseSafe — otimizado, com verificações de segurança
zig build -Doptimize=ReleaseSafe
# ReleaseFast — máxima performance, sem verificações
zig build -Doptimize=ReleaseFast
# ReleaseSmall — menor tamanho do binário
zig build -Doptimize=ReleaseSmall
Escrevendo Código Real
Vamos substituir o src/main.zig gerado por algo mais interessante. Aqui está um programa que demonstra vários conceitos do Zig:
const std = @import("std");
const Tarefa = struct {
descricao: []const u8,
concluida: bool,
pub fn nova(descricao: []const u8) Tarefa {
return .{
.descricao = descricao,
.concluida = false,
};
}
pub fn concluir(self: *Tarefa) void {
self.concluida = true;
}
pub fn exibir(self: Tarefa, writer: anytype) !void {
const status: []const u8 = if (self.concluida) "[x]" else "[ ]";
try writer.print("{s} {s}\n", .{ status, self.descricao });
}
};
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("=== Lista de Tarefas em Zig ===\n\n", .{});
var tarefas = [_]Tarefa{
Tarefa.nova("Instalar o Zig"),
Tarefa.nova("Configurar o editor"),
Tarefa.nova("Criar o primeiro projeto"),
Tarefa.nova("Aprender structs e enums"),
Tarefa.nova("Escrever testes"),
};
// Marcar as primeiras tarefas como concluídas
tarefas[0].concluir();
tarefas[1].concluir();
tarefas[2].concluir();
// Exibir todas as tarefas
for (&tarefas) |*tarefa| {
try tarefa.exibir(stdout);
}
// Contar tarefas concluídas
var concluidas: u32 = 0;
for (tarefas) |t| {
if (t.concluida) concluidas += 1;
}
try stdout.print("\nProgresso: {}/{} tarefas concluidas\n", .{ concluidas, tarefas.len });
}
Execute com:
zig build run
Saída esperada:
=== Lista de Tarefas em Zig ===
[x] Instalar o Zig
[x] Configurar o editor
[x] Criar o primeiro projeto
[ ] Aprender structs e enums
[ ] Escrever testes
Progresso: 3/5 tarefas concluidas
Escrevendo Testes
O Zig tem um sistema de testes integrado. Adicione testes diretamente no mesmo arquivo ou em arquivos separados.
Testes no Próprio Arquivo
Crie src/calculadora.zig:
const std = @import("std");
pub fn somar(a: i32, b: i32) i32 {
return a + b;
}
pub fn subtrair(a: i32, b: i32) i32 {
return a - b;
}
pub fn multiplicar(a: i32, b: i32) i32 {
return a * b;
}
pub fn dividir(a: i32, b: i32) !f64 {
if (b == 0) return error.DivisaoPorZero;
return @as(f64, @floatFromInt(a)) / @as(f64, @floatFromInt(b));
}
// Testes
test "somar numeros positivos" {
try std.testing.expectEqual(@as(i32, 5), somar(2, 3));
try std.testing.expectEqual(@as(i32, 0), somar(-1, 1));
}
test "subtrair numeros" {
try std.testing.expectEqual(@as(i32, 1), subtrair(3, 2));
try std.testing.expectEqual(@as(i32, -5), subtrair(0, 5));
}
test "multiplicar numeros" {
try std.testing.expectEqual(@as(i32, 6), multiplicar(2, 3));
try std.testing.expectEqual(@as(i32, 0), multiplicar(0, 100));
}
test "dividir numeros" {
const resultado = try dividir(10, 2);
try std.testing.expectEqual(@as(f64, 5.0), resultado);
}
test "dividir por zero retorna erro" {
const resultado = dividir(10, 0);
try std.testing.expectError(error.DivisaoPorZero, resultado);
}
Executar os Testes
# Testar o arquivo diretamente
zig test src/calculadora.zig
# Testar via build system
zig build test
Saída esperada:
All 5 passed.
Importar no main.zig
Atualize o src/main.zig para usar a calculadora:
const std = @import("std");
const calc = @import("calculadora.zig");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const a: i32 = 42;
const b: i32 = 8;
try stdout.print("Calculadora Zig\n", .{});
try stdout.print("{} + {} = {}\n", .{ a, b, calc.somar(a, b) });
try stdout.print("{} - {} = {}\n", .{ a, b, calc.subtrair(a, b) });
try stdout.print("{} * {} = {}\n", .{ a, b, calc.multiplicar(a, b) });
if (calc.dividir(a, b)) |resultado| {
try stdout.print("{} / {} = {d:.2}\n", .{ a, b, resultado });
} else |err| {
try stdout.print("Erro na divisão: {}\n", .{err});
}
}
Para que o build.zig reconheça o novo módulo, o src/calculadora.zig é encontrado automaticamente quando importado pelo main.zig usando @import("calculadora.zig").
Estrutura de Projeto Profissional
Para projetos maiores, organize assim:
meu-projeto/
├── build.zig
├── build.zig.zon
├── src/
│ ├── main.zig # Ponto de entrada
│ ├── lib.zig # API pública da biblioteca
│ ├── calculadora.zig # Módulo da calculadora
│ └── utils/
│ └── helpers.zig # Utilitários
├── tests/
│ └── integration.zig # Testes de integração
└── .gitignore
.gitignore para Projetos Zig
# Zig build artifacts
zig-out/
zig-cache/
.zig-cache/
# Editor
.vscode/
.idea/
# OS
.DS_Store
Thumbs.db
Lendo Entrada do Usuário
Aqui está um exemplo de programa interativo que lê entrada do terminal:
const std = @import("std");
pub fn main() !void {
const stdin = std.io.getStdIn().reader();
const stdout = std.io.getStdOut().writer();
try stdout.print("Qual é o seu nome? ", .{});
var buf: [256]u8 = undefined;
if (try stdin.readUntilDelimiterOrEof(&buf, '\n')) |line| {
const nome = std.mem.trimRight(u8, line, "\r\n");
try stdout.print("Olá, {s}! Bem-vindo ao Zig!\n", .{nome});
}
}
Próximos Passos
Com seu primeiro projeto criado:
- Aprenda mais sobre a linguagem — Introdução ao Zig
- Configure seu editor — VS Code, Neovim ou outros
- Gerencie versões — Gerenciar versões do Zig
- Configure CI/CD — GitHub Actions com Zig
- Veja exemplos avançados — Receitas
- Resolva problemas — Erros comuns
Continue praticando e explorando a linguagem. O Zig tem uma curva de aprendizado, mas as recompensas valem o esforço!