Iterator Pattern em Zig — O que é e Como Usar

Iterator Pattern em Zig — O que é e Como Usar

Definição

O Iterator Pattern (padrão de iteração) em Zig segue a convenção de expor um método next() que retorna ?T — ou seja, um optional que é null quando a iteração termina. Diferente de linguagens com traits/interfaces formais de iterador (como Rust ou Java), Zig usa duck typing via anytype ou convenção explícita. Qualquer struct com um método next() que retorne optional pode ser usada como iterador.

Este padrão é usado extensivamente na biblioteca padrão para tokenização de strings, iteração sobre diretórios, leitura de linhas e muito mais.

Por que Iterator Pattern Importa

  1. Avaliação preguiçosa: Dados são produzidos sob demanda, sem alocar tudo na memória.
  2. Composição: Iteradores podem ser encadeados (map, filter, take).
  3. Convenção simples: Apenas next() -> ?T — sem interface formal complexa.
  4. Uso com while: Integra naturalmente com while (iter.next()) |item|.

Exemplo Prático

Iterador Simples

const std = @import("std");

const Intervalo = struct {
    atual: usize,
    fim: usize,

    pub fn init(inicio: usize, fim: usize) Intervalo {
        return .{ .atual = inicio, .fim = fim };
    }

    pub fn next(self: *Intervalo) ?usize {
        if (self.atual >= self.fim) return null;
        const valor = self.atual;
        self.atual += 1;
        return valor;
    }
};

pub fn main() void {
    var iter = Intervalo.init(5, 10);
    while (iter.next()) |valor| {
        std.debug.print("{} ", .{valor}); // 5 6 7 8 9
    }
    std.debug.print("\n", .{});
}

Tokenizador de Strings (da std lib)

const std = @import("std");

pub fn main() void {
    const csv = "nome,idade,cidade,país";

    // std.mem.splitScalar retorna um iterador
    var iter = std.mem.splitScalar(u8, csv, ',');

    while (iter.next()) |campo| {
        std.debug.print("Campo: '{s}'\n", .{campo});
    }
    // Campo: 'nome'
    // Campo: 'idade'
    // Campo: 'cidade'
    // Campo: 'país'
}

Iterador com Estado Complexo

const std = @import("std");

fn Fibonacci() type {
    return struct {
        a: u64 = 0,
        b: u64 = 1,
        contagem: usize = 0,
        limite: usize,

        const Self = @This();

        pub fn init(limite: usize) Self {
            return .{ .limite = limite };
        }

        pub fn next(self: *Self) ?u64 {
            if (self.contagem >= self.limite) return null;
            self.contagem += 1;

            const resultado = self.a;
            const novo = self.a +| self.b; // saturating add
            self.a = self.b;
            self.b = novo;
            return resultado;
        }
    };
}

pub fn main() void {
    var fib = Fibonacci().init(10);
    while (fib.next()) |valor| {
        std.debug.print("{} ", .{valor});
    }
    // 0 1 1 2 3 5 8 13 21 34
    std.debug.print("\n", .{});
}

Convenção do Iterador

// Qualquer struct com este método é um iterador:
pub fn next(self: *Self) ?ItemType {
    // Retornar próximo item ou null se acabou
}

// Uso idiomático:
while (iter.next()) |item| {
    // processar item
}

Iteradores na std lib

IteradorUso
std.mem.splitScalarDividir string por caractere
std.mem.splitSequenceDividir por sequência
std.mem.tokenizeScalarTokenizar ignorando delimitadores consecutivos
std.mem.windowJanela deslizante sobre slice
std.fs.Dir.iterate()Iterar entradas de diretório

Armadilhas Comuns

  • Mutabilidade: O iterador precisa ser var, não const, pois next() modifica estado interno.
  • Consumo único: A maioria dos iteradores só pode ser percorrida uma vez. Para percorrer novamente, crie outro iterador.
  • Sem reset: Não há convenção de “reset” — crie uma nova instância.
  • null vs fim: null significa “sem mais itens”, não erro. Para iteradores que podem falhar, o retorno deve ser !?T.

Termos Relacionados

  • Optional — Tipo de retorno ?T do next()
  • Struct — Iteradores são structs com estado
  • anytype — Funções genéricas aceitam qualquer iterador
  • Slice — Fonte comum de dados para iteração

Tutoriais Relacionados

Continue aprendendo Zig

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