Событие OnMouseDown принимает замыкание в качестве параметра, который в принципе может захватывать любую переменную области действия, в которой он был создан.
Вот пример кода из документации на http://tutor.rascal-mpl.org/Rascal/Libraries/Vis/Figure/Properties/onMouseDown/onMouseDown.html, расширенный «дополнительной информацией»:
import vis::KeySym;
s = "";
s2 = "";
extraInformation = "some additional info about the b box"; // definition of extra information
b = box(text(str () { return s; }),
fillColor("red"),
onMouseDown(bool (int butnr, map[KeyModifier,bool] modifiers) {
s = "<butnr>" + extraInformation; // later use of extra information
return true;
}));
Важно понимать, что замыкание / Лямбда фиксирует привязки к переменным , а не к их значениям . Таким образом, содержимое переменной extraInformation
изменяется, если какой-то другой код, который захватывает эту же переменную, меняет ее. В этом примере это происходит для переменной s
, но не для переменной extraInformation
, поскольку никто не присваивает ей переменную после первоначального объявления.
Итак, следите за связыванием переменных l oop из for
циклы и понимания: они всегда имеют содержимое последней итерации l oop. Чтобы обойти это, введите дополнительную переменную, такую как:
boxes = [box(..., onMouseDown(..., bool (int butnr, map[KeyModifier,bool] modifiers) { use of var })) | x <- elements, var := x];
или примерно так:
boxes = for (x <- elements) {
var = x;
append box(..., onMouseDown(..., bool (int butnr, map[KeyModifier,bool] modifiers) { use of var }));
}
Если бы мы использовали x
вместо var
в замыкании все ваши ящики будут иметь одинаковое значение для x
, который является последним элементом elements
. W