Anonymous Methods e Closures no Delphi 2009
Já conhecemos a sintaxe dos anonymous methods do Delphi 2009. A parte interessante deste novo recurso é que eles são closures.
Closure é a união do código com o seu escopo. Isso quer dizer que o novo método tem acesso às variáveis locais do método que o criou, mesmo depois que ele terminou. Vamos ver como isso funciona com um exemplo:
type
TContador = reference to function: Integer;
function CriaContador(Inicial, Final: Integer): TContador;
var
i: Integer;
begin
i := Inicial;
Result := function: Integer
begin
Result := i;
Inc(i);
if i > Final then
i := Inicial;
end;
end;
var
Contador: TContador;
i: Integer;
begin
Contador := CriaContador(5, 12);
for i := 0 to 20 do
WriteLn(Contador);
end.
Antes de ver a listagem da saída do programa, Vamos entender o código. TContador é um tipo que representa uma referência a uma função que retorna um número. Neste caso, vai retornar uma sequência de números, um número novo cada vez que for chamada. CriaContador é uma função que retorna um método desse tipo, recebendo os valores inicial e final que a sequência vai ter. Repare que o corpo de CriaContador tem apenas duas linhas de código que serão executadas quando ela for chamada: ela inicializa o contador, e atribui um novo método para o resultado.
No corpo do programa criamos um novo contador na faixa 5 até 12, e chamamos essa função 21 vezes, escrevendo o resultado no console. Em cada chamada da função, ela retorna o valor atual de i, o incrementa, e caso tenha passado do valor final, volta ao primeiro.
Quais serão os 21 números escritos no console?
5 6 7 8 9 10 11 12 5 6 7 8 9 10 11 12 5 6 7 8 9
Ou seja, o programa funciona exatamente como descrevi.
Cada instância do método captura o escopo daquele momento. Se criarmos dois contadores:
var
Contador, Contador2: TContador;
i: Integer;
begin
Contador := CriaContador(5, 8);
Contador2 := CriaContador(1, 3);
for i := 0 to 5 do
WriteLn(Contador,':',Contador2);
end.
podemos ver que eles funcionam de forma completamente independente:
5:1 6:2 7:3 8:1 5:2 6:3
Essa é uma nova técnica possível no Delphi 2009. Para implementar o equivalente sem este recurso, seria necessário criar classes para o contador, construir instâncias e liberá-las. Ou seja, muito mais código e complicação.
O Craig Stuntz escreveu um exemplo muito interessante utilizando esse método pra implementar o Crivo de Eratóstenes. Ele entrou no assunto da técnica de currying, que vai ficar para o próximo artigo.
Em 23 de setembro de 2008 às 13:21
Mt bom estes artigos sobre Delphi 2009….e parabéns pelo site q tah nota 10000000000…..
Tem artigos mt bons q geralmente só são encontrados em inglês….parabéns pela iniciativa…
se vc puder….mostrar mais exemplos sobre anonymous methods, closures e tbm generics…toda comunidade ficaria grata…
Obrigado….
Em 20 de outubro de 2008 às 16:43
Parabens!!!!
Em 27 de outubro de 2008 às 02:39
Muito bom artigo. Creio que nunc aprecirei usar esse recurso porém é sempre bom estar atento.
Só não to gostando de ver 1 delphi novo a cada ano. o_0
Em 06 de novembro de 2009 às 14:19
Parabéns.. muito útil, site ta muito bom
valeu