How to create delegates with an independent scope?
Tejas
notrealemail at gmail.com
Wed Mar 30 15:49:24 UTC 2022
On Wednesday, 30 March 2022 at 12:46:07 UTC, Vijay Nayar wrote:
> Consider the following code example:
>
> ```d
> import std.stdio;
>
> void main()
> {
> alias DelegateT = string delegate();
>
> // An array of delegates, each has their own scope.
> DelegateT[] funcs;
> foreach (i; ["ham", "cheese"]) {
> // Deliberately create a copy to keep in delegate scope.
> string myStr = i.dup;
> // The delegate will hopefully carry this copy around in
> its own scope.
> funcs ~= (() => myStr ~ " sandwich");
> }
>
> foreach (f; funcs) {
> writeln(f());
> }
> }
> ```
>
> The expected output is: "ham sandwich" and then "cheese
> sandwich".
>
> The actual output is: "cheese sandwich" and then "cheese
> sandwich".
>
> It seems that the variable `myStr` is in a sort of shared scope
> for both functions in the array, and the last value written to
> it dominates.
>
> How do I create a delegate that acts like a
> [closure](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures), that is, it carries with it the environment in which it was created?
You can also use `static foreach` and `alias`, although that will
restrict that code to compile time usage only :/
```d
import std;
import std.stdio;
void main()
{
alias DelegateT = string delegate();
// An array of delegates, each has their own scope.
DelegateT[] funcs;
static foreach (alias i; ["ham", "cheese"]) {
// Deliberately create a copy to keep in delegate scope.
//string myStr = i.dup;
// The delegate will hopefully carry this copy around in its
own scope.
funcs ~= (() => /*myStr*/ i ~ " sandwich");
}
foreach (f; funcs) {
writeln(f());
}
}
```
More information about the Digitalmars-d-learn
mailing list