Anonymous Methods e Closures no Delphi 2009

Escrito em 29 de agosto de 2008 em Linguagem Delphi por Leonel Togniolli

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.


4 comentários em 'Anonymous Methods e Closures no Delphi 2009' »

Assine os comentários usando RSS ou faça um TrackBack para 'Anonymous Methods e Closures no Delphi 2009'.

[-]
[+]
Williame Rocha disse,

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…. :-)

 
[-]
[+]
Jose Carlos Castelli disse,

Em 20 de outubro de 2008 às 16:43

Parabens!!!!

 
[-]
[+]
Thiago disse,

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

 
[-]
[+]
Jonathan disse,

Em 06 de novembro de 2009 às 14:19

Parabéns.. muito útil, site ta muito bom
valeu