Cheatsheet: Biblioteca Padrão Essencial em Zig
A biblioteca padrão (std) de Zig é abrangente e cuidadosamente projetada. Este cheatsheet cobre os módulos e funções que você vai usar com mais frequência no dia a dia. A std é importada com const std = @import("std"); e organizada em namespaces lógicos.
Visão Geral dos Módulos
| Módulo | Descrição |
|---|
std.mem | Operações de memória e comparação |
std.fmt | Formatação de strings |
std.fs | Sistema de arquivos |
std.io | Entrada/saída |
std.heap | Alocadores de memória |
std.math | Funções matemáticas |
std.time | Tempo e temporizadores |
std.json | Parsing e serialização JSON |
std.crypto | Criptografia |
std.http | Cliente HTTP |
std.log | Sistema de logging |
std.debug | Depuração |
std.os | Interface com o sistema operacional |
std.process | Processos e argumentos |
std.sort | Algoritmos de ordenação |
std.unicode | Suporte a Unicode |
std.ArrayList — Lista Dinâmica
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const alloc = gpa.allocator();
// Criar lista
var lista = std.ArrayList(i32).init(alloc);
defer lista.deinit();
// Adicionar elementos
try lista.append(10);
try lista.append(20);
try lista.append(30);
try lista.appendSlice(&[_]i32{ 40, 50 });
// Acessar
std.debug.print("Primeiro: {d}\n", .{lista.items[0]});
std.debug.print("Tamanho: {d}\n", .{lista.items.len});
// Iterar
for (lista.items) |item| {
std.debug.print("{d} ", .{item});
}
// Remover
_ = lista.orderedRemove(1); // remove índice 1 mantendo ordem
_ = lista.swapRemove(0); // remove índice 0 (troca com último, O(1))
// Redimensionar
try lista.resize(10); // agora tem 10 elementos
// Limpar sem liberar memória
lista.clearRetainingCapacity();
// Converter para slice owned
const slice = try lista.toOwnedSlice();
defer alloc.free(slice);
}
std.HashMap — Mapa Hash
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const alloc = gpa.allocator();
// HashMap com chave string
var mapa = std.StringHashMap(i32).init(alloc);
defer mapa.deinit();
// Inserir
try mapa.put("idade", 25);
try mapa.put("pontos", 100);
// Buscar
if (mapa.get("idade")) |valor| {
std.debug.print("Idade: {d}\n", .{valor});
}
// Verificar existência
const existe = mapa.contains("nome");
std.debug.print("Tem 'nome': {}\n", .{existe});
// Remover
_ = mapa.remove("pontos");
// Iterar
var iter = mapa.iterator();
while (iter.next()) |entrada| {
std.debug.print("{s} = {d}\n", .{ entrada.key_ptr.*, entrada.value_ptr.* });
}
// Tamanho
std.debug.print("Entradas: {d}\n", .{mapa.count()});
// HashMap com chave inteira
var mapa_int = std.AutoHashMap(u32, []const u8).init(alloc);
defer mapa_int.deinit();
try mapa_int.put(1, "um");
try mapa_int.put(2, "dois");
}
std.mem — Operações de Memória
const std = @import("std");
pub fn main() void {
const dados = "Olá, Zig Brasil!";
// Buscar substring
if (std.mem.indexOf(u8, dados, "Zig")) |pos| {
std.debug.print("'Zig' na posição {d}\n", .{pos});
}
// Comparar
const iguais = std.mem.eql(u8, "abc", "abc"); // true
std.debug.print("Iguais: {}\n", .{iguais});
// Começar com / terminar com
const comeca = std.mem.startsWith(u8, dados, "Olá");
const termina = std.mem.endsWith(u8, dados, "!");
std.debug.print("Começa com 'Olá': {}\n", .{comeca});
std.debug.print("Termina com '!': {}\n", .{termina});
// Split
var iter = std.mem.splitSequence(u8, "a,b,c,d", ",");
while (iter.next()) |parte| {
std.debug.print("Parte: {s}\n", .{parte});
}
// Trim
const trimmed = std.mem.trim(u8, " texto ", " ");
std.debug.print("Trimmed: '{s}'\n", .{trimmed});
// Substituir
var buffer: [100]u8 = undefined;
const resultado = std.mem.replace(u8, "aXbXc", "X", "_", &buffer);
_ = resultado;
// Preencher
var buf: [10]u8 = undefined;
@memset(&buf, 0); // preencher com zeros
// Copiar
var destino: [10]u8 = undefined;
@memcpy(destino[0..5], "Hello");
}
std.sort — Ordenação
const std = @import("std");
pub fn main() void {
var nums = [_]i32{ 5, 2, 8, 1, 9, 3, 7, 4, 6 };
// Ordenar com comparação padrão
std.mem.sort(i32, &nums, {}, std.sort.asc(i32));
// nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
// Ordenar decrescente
std.mem.sort(i32, &nums, {}, std.sort.desc(i32));
// nums = [9, 8, 7, 6, 5, 4, 3, 2, 1]
// Busca binária (em array ordenado)
std.mem.sort(i32, &nums, {}, std.sort.asc(i32));
const resultado = std.sort.binarySearch(i32, &nums, @as(i32, 5), {}, struct {
fn f(_: void, val: i32, item: i32) std.math.Order {
return std.math.order(val, item);
}
}.f);
if (resultado) |idx| {
std.debug.print("5 encontrado no índice {d}\n", .{idx});
}
}
std.math — Funções Matemáticas
const std = @import("std");
const math = std.math;
pub fn main() void {
// Constantes
std.debug.print("Pi: {d}\n", .{math.pi});
std.debug.print("E: {d}\n", .{math.e});
// Funções básicas
std.debug.print("abs(-5): {d}\n", .{@abs(@as(i32, -5))});
std.debug.print("max(3,7): {d}\n", .{@max(@as(i32, 3), 7)});
std.debug.print("min(3,7): {d}\n", .{@min(@as(i32, 3), 7)});
std.debug.print("clamp(15,0,10): {d}\n", .{std.math.clamp(@as(i32, 15), 0, 10)});
// Funções trigonométricas
std.debug.print("sin(π/2): {d}\n", .{@sin(@as(f64, math.pi / 2.0))});
std.debug.print("cos(0): {d}\n", .{@cos(@as(f64, 0.0))});
// Potência e raiz
std.debug.print("sqrt(144): {d}\n", .{@sqrt(@as(f64, 144.0))});
std.debug.print("log2(8): {d}\n", .{@log2(@as(f64, 8.0))});
std.debug.print("log10(100): {d}\n", .{@log10(@as(f64, 100.0))});
// Overflow checked
const resultado = math.add(i32, 2_000_000_000, 1_000_000_000);
if (resultado) |val| {
std.debug.print("Soma: {d}\n", .{val});
} else |_| {
std.debug.print("Overflow!\n", .{});
}
}
std.json — JSON
const std = @import("std");
const Pessoa = struct {
nome: []const u8,
idade: u32,
ativo: bool,
};
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const alloc = gpa.allocator();
// Parse JSON
const json_str =
\\{"nome": "Ana", "idade": 25, "ativo": true}
;
const parsed = try std.json.parseFromSlice(Pessoa, alloc, json_str, .{});
defer parsed.deinit();
const pessoa = parsed.value;
std.debug.print("Nome: {s}, Idade: {d}\n", .{ pessoa.nome, pessoa.idade });
// Serializar para JSON
const p = Pessoa{ .nome = "Carlos", .idade = 30, .ativo = true };
var buf = std.ArrayList(u8).init(alloc);
defer buf.deinit();
try std.json.stringify(p, .{}, buf.writer());
std.debug.print("JSON: {s}\n", .{buf.items});
}
std.http — Cliente HTTP
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const alloc = gpa.allocator();
// Cliente HTTP
var client = std.http.Client{ .allocator = alloc };
defer client.deinit();
// Fazer requisição GET
const uri = try std.Uri.parse("https://api.exemplo.com/dados");
var req = try client.open(.GET, uri, .{
.server_header_buffer = &[_]u8{} ** 4096,
});
defer req.deinit();
try req.send();
try req.wait();
// Ler resposta
var body = std.ArrayList(u8).init(alloc);
defer body.deinit();
try req.reader().readAllArrayList(&body, 1024 * 1024);
std.debug.print("Resposta: {s}\n", .{body.items});
}
std.time — Tempo
const std = @import("std");
pub fn main() !void {
// Timestamp Unix
const timestamp = std.time.timestamp();
std.debug.print("Timestamp: {d}\n", .{timestamp});
// Medir duração
var timer = try std.time.Timer.start();
// ... operação ...
std.time.sleep(100 * std.time.ns_per_ms); // dormir 100ms
const elapsed = timer.read();
std.debug.print("Tempo: {d}ms\n", .{elapsed / std.time.ns_per_ms});
// Constantes úteis
_ = std.time.ns_per_s; // nanossegundos por segundo
_ = std.time.ns_per_ms; // nanossegundos por milissegundo
_ = std.time.ns_per_us; // nanossegundos por microssegundo
}
std.process — Processos e Argumentos
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const alloc = gpa.allocator();
// Argumentos da linha de comando
var args = try std.process.argsWithAllocator(alloc);
defer args.deinit();
while (args.next()) |arg| {
std.debug.print("Arg: {s}\n", .{arg});
}
// Variáveis de ambiente
const home = std.process.getEnvVarOwned(alloc, "HOME") catch "desconhecido";
defer if (!std.mem.eql(u8, home, "desconhecido")) alloc.free(home);
std.debug.print("HOME: {s}\n", .{home});
// Executar processo filho
var child = std.process.Child.init(.{
.argv = &.{ "ls", "-la" },
.allocator = alloc,
});
_ = try child.spawnAndWait();
}
std.Random — Números Aleatórios
const std = @import("std");
pub fn main() void {
var prng = std.Random.DefaultPrng.init(blk: {
var seed: u64 = undefined;
std.posix.getrandom(std.mem.asBytes(&seed)) catch unreachable;
break :blk seed;
});
const random = prng.random();
// Inteiro aleatório
const num = random.int(u32);
std.debug.print("Aleatório u32: {d}\n", .{num});
// Inteiro em range
const dado = random.intRangeAtMost(u8, 1, 6);
std.debug.print("Dado: {d}\n", .{dado});
// Float aleatório [0, 1)
const f = random.float(f64);
std.debug.print("Float: {d}\n", .{f});
// Embaralhar array
var nums = [_]i32{ 1, 2, 3, 4, 5 };
random.shuffle(i32, &nums);
}
Referência Rápida
| Operação | Código |
|---|
| Lista dinâmica | std.ArrayList(T).init(alloc) |
| HashMap string | std.StringHashMap(V).init(alloc) |
| HashMap genérico | std.AutoHashMap(K, V).init(alloc) |
| Ordenar | std.mem.sort(T, slice, ctx, cmpFn) |
| Split string | std.mem.splitSequence(u8, str, delim) |
| Trim | std.mem.trim(u8, str, chars) |
| Buscar | std.mem.indexOf(u8, str, substr) |
| Comparar | std.mem.eql(u8, a, b) |
| Parse JSON | std.json.parseFromSlice(T, alloc, str, .{}) |
| Formatar | std.fmt.allocPrint(alloc, fmt, args) |
| Timestamp | std.time.timestamp() |
| Dormir | std.time.sleep(ns) |
Veja Também