Local variable inside delegate literal

Daniel yebbliesnospam at gmail.com
Wed Dec 23 01:30:49 PST 2009


bearophile Wrote:

> Daniel:
> 
> > I'm writing some gui code, and am currently trying to make something equivalent to this:
> > 
> > int delegate()[] funcs;
> > funcs.length = 3;
> > 
> > foreach(i, ref f; funcs)
> > {
> >   f = int() { return i; }
> > }
> > 
> > foreach(f; funcs)
> > {
> >   writeln(f());
> > }
> 
> This is D2 code that actually compiles:
> 
> import std.stdio: writeln;
> 
> void main() {
>     auto funcs = new int delegate()[3];
> 
>     foreach (i, ref f; funcs)
>         f = { return cast(int)i; };
> 
>     foreach (f; funcs)
>         writeln(f());
> }
> 
> 
> This is a good version in D2:
> 
> import std.stdio: writeln;
> 
> class Foo {
>     int i;
>     this(int i) { this.i = i; }
>     int opCall() { return this.i; }
> }
> 
> void main() {
>     auto funcs = new Foo[3];
> 
>     foreach (i, ref f; funcs)
>         f = new Foo(i);
> 
>     foreach (f; funcs)
>         writeln(f());
> }
> 
> 
> Or even cheaper:
> 
> import std.stdio: writeln;
> 
> struct Foo {
>     int i;
>     this(int i) { this.i = i; }
>     int opCall() { return this.i; }
> }
> 
> void main() {
>     auto funcs = new Foo[3];
> 
>     foreach (i, ref f; funcs)
>         f = Foo(i);
> 
>     foreach (f; funcs)
>         writeln(f());
> }
> 
> Often the better code is not the most compact one, but the most explicit one.
> 
> Bye,
> bearophile

I actually needed it to be a delegate to interact with the rest of my code, but I used the idea of making a copy of the index variable each loop iteration, using a generating function returning a closure.

Thanks for your help.



import std.stdio: writeln;

void main() {
    auto funcs = new int delegate()[3];

    int delegate() makedg(int i)
    {
        return { return i; };
    }

    foreach (i, ref f; funcs)
        f = makedg(i);

    foreach (f; funcs)
        writeln(f());
}

Or

void main() {
    auto funcs = new int delegate()[3];

    foreach (i, ref f; funcs)
        f = (int i) { return { return i; }; }(i);

    foreach (f; funcs)
        writeln(f());
}



More information about the Digitalmars-d mailing list