我正在尝试在 Rascal 中绘制一些框,并尝试为每个框提供自己的回调函数。使用鼠标进入框时,相应的字符串应显示在文本元素中(因此悬停 box1 应显示 box1 等)。
但是,目前文本确实会弹出,但仅为 3 个框显示“box3”。
有什么想法吗?
strings = ["box1", "box2", "box3"];
boxes = [ box(
size(100, 100),
onMouseEnter(void() {
output = s;
})
) | s <- strings];
render(hcat([
vcat(boxes),
text(str () {return output;})
]));
最佳答案
好问题,经典问题。问题的本质是 Rascal 使用“非捕获闭包”:这意味着从另一个函数返回的函数共享相同的上下文。在您的情况下,这是变量 s
由s <- strings
介绍。当您在循环中创建函数值时(正如您在此处所做的那样),这种情况几乎总是会发生。解决方案是在返回的函数周围包装另一个函数层。
这是一个简单的例子:
list[int()] makeClosures()
= [ int() {return i;} | i <- [0,1,2]];
void wrong(){
lst = makeClosures();
println(lst[0]());
println(lst[1]());
println(lst[2]());
}
这将令人惊讶地打印值 2,
2 and
2`.如前所述,解决方案是引入另一个功能级别:
int() makeClosure(int i)
= int() { return i;};
list[int()] makeClosuresOK()
= [ makeClosure(i) | i <- [0,1,2]];
void right(){
lst = makeClosuresOK();
println(lst[0]());
println(lst[1]());
println(lst[2]());
}
现在调用right()
将打印1
, 2
,和3
正如预期的那样。
我将其作为练习,在您的示例中如何完成此操作,但我准备在您要求时提供解决方案。祝你好运!
关于rascal - 在 Rascal 中返回相同字符串的框回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54278043/