How to create delegates with an independent scope?

vit vit at vit.vit
Wed Mar 30 12:53:10 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?

use two delegates :)

```d
import std;

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());
	}
}
```



More information about the Digitalmars-d-learn mailing list