Sobes.tech
Middle

Qual é o papel dos geradores na linguagem PHP e como eles diferem dos iteradores?

sobes.tech IA

Resposta da IA

Os geradores em PHP permitem criar iteradores sem implementar a interface Iterator. Utilizam a palavra-chave yield para devolver valores um a um, suspendendo a execução da função até à próxima iteração.

Diferenças em relação aos iteradores:

  • Implementação: Os iteradores requerem a implementação das interfaces Iterator (current, key, next, rewind, valid), o que pode ser verboso para casos simples. Os geradores são implementados como funções com yield.
  • Memória: Os geradores consomem menos memória ao trabalhar com grandes conjuntos de dados, pois geram os valores "em tempo real" em vez de carregar todo o conjunto na memória. Os iteradores podem carregar ou processar dados na sua totalidade, dependendo da sua implementação.
  • Sintaxe: A sintaxe dos geradores é mais simples e legível para criar iteradores simples.
  • Estado: Os geradores mantêm automaticamente o seu estado interno entre chamadas a next. Nos iteradores, a gestão do estado fica a cargo do programador.

Exemplo de uso de um gerador:

<?php
// Gerador simples para números
function generateNumbers(int $limit) {
    for ($i = 0; $i <= $limit; $i++) {
        yield $i;
    }
}

// Uso do gerador
foreach (generateNumbers(5) as $number) {
    echo $number . " "; // Saída: 0 1 2 3 4 5
}

Exemplo de uso de um iterador básico (para comparação, não é um exemplo completo):

<?php
// Implementação simples de Iterator (para comparação)
class SimpleIterator implements Iterator {
    private array $items = [];
    private int $position = 0;

    public function __construct(array $items) {
        $this->items = $items;
    }

    public function current(): mixed { /*...*/ }
    public function key(): mixed { /*...*/ }
    public function next(): void { /*...*/ }
    public function rewind(): void { /*...*/ }
    public function valid(): bool { /*...*/ }
}

Os geradores são úteis para carregamento preguiçoso de dados (por exemplo, leitura de grandes ficheiros linha por linha) e para criar sequências finitas ou infinitas sem consumo excessivo de memória. Os iteradores, por outro lado, são mais flexíveis e podem ser utilizados para estruturas de dados mais complexas e lógica de iteração.