Cheatsheet: Biblioteca Padrão Essencial em Zig

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óduloDescrição
std.memOperações de memória e comparação
std.fmtFormatação de strings
std.fsSistema de arquivos
std.ioEntrada/saída
std.heapAlocadores de memória
std.mathFunções matemáticas
std.timeTempo e temporizadores
std.jsonParsing e serialização JSON
std.cryptoCriptografia
std.httpCliente HTTP
std.logSistema de logging
std.debugDepuração
std.osInterface com o sistema operacional
std.processProcessos e argumentos
std.sortAlgoritmos de ordenação
std.unicodeSuporte 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çãoCódigo
Lista dinâmicastd.ArrayList(T).init(alloc)
HashMap stringstd.StringHashMap(V).init(alloc)
HashMap genéricostd.AutoHashMap(K, V).init(alloc)
Ordenarstd.mem.sort(T, slice, ctx, cmpFn)
Split stringstd.mem.splitSequence(u8, str, delim)
Trimstd.mem.trim(u8, str, chars)
Buscarstd.mem.indexOf(u8, str, substr)
Compararstd.mem.eql(u8, a, b)
Parse JSONstd.json.parseFromSlice(T, alloc, str, .{})
Formatarstd.fmt.allocPrint(alloc, fmt, args)
Timestampstd.time.timestamp()
Dormirstd.time.sleep(ns)

Veja Também

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.