Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
December 23, 2009 Local variable inside delegate literal | ||||
---|---|---|---|---|
| ||||
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()); } Prints: 3 3 3 I want it to print 0 1 2 Is there anyway to get this behaviour using delegate literals initialized with a runtime loop? |
December 23, 2009 Re: Local variable inside delegate literal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel | 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
|
December 23, 2009 Re: Local variable inside delegate literal | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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());
}
|
December 23, 2009 Re: Local variable inside delegate literal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel | Daniel wrote:
> 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());
> }
>
> Prints:
> 3
> 3
> 3
>
> I want it to print
> 0
> 1
> 2
>
> Is there anyway to get this behaviour using delegate literals initialized with a runtime loop?
This is how you do it in 1.0:
import std.stdio, std.bind;
void main() {
auto funcs = new int delegate()[3];
foreach (i, ref f; funcs)
f = bind((int i) { return i; }, i).ptr();
foreach (f; funcs)
writefln(f());
}
--outputs--
0
1
2
|
December 23, 2009 Re: Local variable inside delegate literal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel | Daniel wrote:
> int delegate()[] funcs;
> funcs.length = 3;
>
> foreach(i, ref f; funcs)
> {
> f = int() { return i; }
> }
>
> foreach(f; funcs)
> {
> writeln(f());
> }
First, there are syntax errors in your example. It should be
f = delegate int() { return i; };
Second, this works in D2:
foreach(i, ref f; funcs)
{
void blah() {
auto j = i;
f = delegate int() { return j; };
}
blah();
}
But this doesn't, outputs 2, 2, 2:
foreach(i, ref f; funcs)
{
auto j = i;
f = delegate int() { return j; };
}
And this crashes:
foreach(i, ref f; funcs)
{
({
auto j = i;
f = delegate int() { return j; };
})();
}
I think these 3 variants should be equivalent.
|
Copyright © 1999-2021 by the D Language Foundation