How to avoid variable capturing in `foreach` loop with lambdas?
thebluepandabear
therealbluepandabear at protonmail.com
Thu Jan 5 22:46:07 UTC 2023
On Thursday, 5 January 2023 at 17:36:55 UTC, H. S. Teoh wrote:
> On Thu, Jan 05, 2023 at 11:55:33AM +0000, thebluepandabear via
> Digitalmars-d-learn wrote: [...]
>> ```D
>> foreach (BoardSize boardSize; arr) {
>> Button button = new Button();
>> button.text = format("%sx%s", boardSize[0], boardSize[1]);
>> button.onButtonClick = {
>> eventHandler.settingsWindow_onBoardSizeButtonClick(boardSize);
>> };
>> button.onButtonClick();
>> _boardSizeRow.addChild(button);
>> }
>> ```
>
> This is a classic D trap: the loop variable is only allocated
> once, and the closure captures the single location where the
> loop variable resides, thus every delegate from every loop
> iteration will see the same value when they are run later,
> i.e., the last value of the loop index. Do this instead:
>
> ```D
> foreach (BoardSize boardSize; arr) {
> Button button = new Button();
> button.text = format("%sx%s", boardSize[0], boardSize[1]);
> BoardSize size = boardSize; // force separate capture
> button.onButtonClick = {
>
> eventHandler.settingsWindow_onBoardSizeButtonClick(size);
> };
> button.onButtonClick();
> _boardSizeRow.addChild(button);
> }
> ```
>
> This is arguably a language bug (I can't imagine any sane use
> case where somebody would actually want the current semantics).
> But we have not be successful in convincing Walter about
> this...
>
>
> T
Your code with the variable capture doesn't seem to work.
More information about the Digitalmars-d-learn
mailing list