A delegate problem, create delegation in loop

Timon Gehr timon.gehr at gmx.ch
Fri Jul 6 00:06:55 PDT 2012


On 07/06/2012 05:14 AM, lijie wrote:
> On Thu, Jul 5, 2012 at 4:26 PM, Denis Shelomovskij
> <verylonglogin.reg at gmail.com <mailto:verylonglogin.reg at gmail.com>> wrote:
>
>     Different situation is for such C# loop:
>     ---
>     for (int i = 0; i < funcs.Length; ++i)
>     {
>          int t = i;
>          funcs[i] = new MyFunc(() => System.Console.WriteLine(t));
>     }
>     ---
>     where "t" is local for scope. Here C# behaves correctly, but D
>     doesn't. This D loop
>     ---
>     foreach(i; 0 .. 5) {
>          int t = i;
>          functions ~= { printf("%d\n", t); };
>     }
>     ---
>     prints "4" five times. It's Issue 2043:
>     http://d.puremagic.com/issues/__show_bug.cgi?id=2043
>     <http://d.puremagic.com/issues/show_bug.cgi?id=2043>
>
> How to distinguish which variables will be copied to the closure context?
>

They are not copied, they are stored there.

> I think this is a scope rule, in the previous code, there are three
> variables:
> 1. function arguments
> 2. loop variables
> 3. local variables
> Seems only function parameters is copied. In C#, local variables is
> copied. There are other rules? And why is the loop variable not local?
>
> Thanks.
>
> Best regards,
>
> -- Li Jie

It is simple. Variable declarations introduce a new variable. Closures
that reference the same variable will see the same values.

----

foreach(i; 0..3) { functions~={writeln(i);}; }

is the same as

for(int i=0;i<3;i++) { functions~={writeln(i);}; }

is the same as

{int i=0;for(;i<3;i++) { functions~={writeln(i);}; }}

is the same as

{
     int i=0;
     { functions~={writeln(i);}; }
     i++;
     { functions~={writeln(i);}; }
     i++;
     { functions~={writeln(i);}; }
     i++;
}


----

foreach(i; 0..3){ int j=i; functions~={writeln(j);}; }

is the same as

for(int i=0;i<3;i++){ int j=i; functions~={writeln(j);}; }

is the same as

{int i=0;for(i<3;i++){ int j=i; functions~={writeln(j);}; }

is the same as

{
     int i=0;
     { int j=i; functions~={writeln(j);}; }
     i++;
     { int j=i; functions~={writeln(j);}; }
     i++;
     { int j=i; functions~={writeln(j);}; }
     i++;
}

----

I think it is quite intuitive.



More information about the Digitalmars-d mailing list