On 06/04/2013 11:03 PM, Nick Sabalausky wrote:
On Tue, 04 Jun 2013 21:19:56 +0200
"Idan Arye" <generic...@gmail.com> wrote:

Consider the following code. What will it print?

      auto arr=new ulong delegate()[5];

      foreach(i;0..arr.length){
          arr[i]=()=>i;
      }

      writeln(arr.map!`a()`());

It is natural to expect that it will print [0, 1, 2, 3, 4], but
it actually prints [5, 5, 5, 5, 5]. The reason is obvious - all
the delegates refer to the same `i` in their closures, and at the
end of the loop that `i` is set to `5`.


I think the problem is simply a misunderstanding of closures.
...

I believe what you explain is exactly what he suspected is happening.

...

So when you put the delegate creation in a loop:

     foreach(a; iota(0..6))
         dg = () => a;

It *is* expected that you're *not* sticking 0, 1, 2, 3, etc inside the
delegate. That's because you're not evaluating "a" *at all* here,
you're just crerates a delegate that *refers* to "a" itself. You're
just creating the exact same delegate five times. In other words:

You're just saying:
Store the following set of instructions into 'dg': "Read the value of
'a' and then return it."

You're *not* saying:
Read the value of 'a' and *then* create a delegate that returns that
value.



'a' refers to a different location for every loop iteration. This is a language change in 2.063.

Reply via email to