How to avoid variable capturing in `foreach` loop with lambdas?
tsbockman
thomas.bockman at gmail.com
Thu Jan 5 13:58:30 UTC 2023
On Thursday, 5 January 2023 at 13:05:46 UTC, thebluepandabear
wrote:
> Update some time later: the only way (oof!) around this seems
> to be using a `static foreach` with arrays:
>
> ```D
> Button[3] b;
>
> static foreach (indx, BoardSize boardSize; arr) {
> b[indx] = new Button();
> b[indx].text = format("%sx%s", boardSize[0], boardSize[1]);
> b[indx].onButtonClick = {
>
> eventHandler.settingsWindow_onBoardSizeButtonClick(boardSize);
> };
> _boardSizeRow.addChild(b[indx]);
> }
> ```
This is semantically equivalent to copying and pasting the loop
body `arr.length` number of times, substituting the expression
`arr[indx]` for `boardSize`, and the literal value of `indx` for
`indx`.
Unlike with a runtime (non-`static`) loop, the event handler
closure does not capture a reference to `boardSize` or `indx`,
because they don't actually exist at runtime and so cannot be
referenced. Instead, `arr.length` different event handler
functions are created at compile time, with each having the
appropriate `indx` literal substituted.
So, while it does work as long as `arr.length` is known at
compile time, it will cause a ton of needless code bloat unless
`arr.length` is very small.
> Any other ways of fixing this annoying issue?
Yes, see [my earlier
reply](https://forum.dlang.org/post/fwnccjunvnffmtaholqc@forum.dlang.org) for an explanation of how to get your original run time loop working as intended.
More information about the Digitalmars-d-learn
mailing list