将方法作为参数传递给 Java 方法

Pass method as argument to Java method

我有一些 java 代码要转换为 Xtend。 Java代码是:

public void createPartControl(Composite parent) {
    final Canvas clock = new Canvas(parent, SWT.None);
    clock.addPaintListener(this::drawClock);
}

private void drawClock(PaintEvent e) {
    e.gc.drawArc(e.x, e.y, e.width - 1, e.height - 1, 0, 360);
}

我对 Xtend 代码的尝试是:

override createPartControl(Composite parent) {
    val clock = new Canvas(parent, SWT.None);
    clock.addPaintListener(this::drawClock);
}

private def drawClock(PaintEvent e) {
    e.gc.drawArc(e.x, e.y, e.width - 1, e.height - 1, 0, 360);
}

问题是表达式 this::drawClock 在 Xtend 中无效。具体来说,它说 this 无法解析为类型。我如何使用 Xtend 获得相同的结果。

Xtend 不支持方法引用。您需要将要调用的方法包装在 Xtend lambda 中。

this::drawClock 或 Java 中的 (e) -> drawClock(e) 在 Xtend 中变为 [drawClock]。自动推断类型。

所以你可以这样写:

override createPartControl(Composite parent) {
    val clock = new Canvas(parent, SWT.None)
    clock.addPaintListener[drawClock]
}

监听器的PaintEvent参数是lambda的隐式it参数。它自动用作 drawClock 的第一个参数。对于带有 lambda 参数的方法调用,括号是可选的。

我会说符号 addPaintListener[drawClock] 是惯用的,但你当然也可以写得更明确。所有这些都是等价的:

clock.addPaintListener[drawClock]
clock.addPaintListener([drawClock])
clock.addPaintListener([drawClock(it)])
clock.addPaintListener([e|drawClock(e)])
clock.addPaintListener([PaintEvent e| e.drawClock])

如果该方法有多个参数,您可以将这些参数显式添加到 lambda 或使用隐式 ,,...,$n 参数,例如:

component.addFooListener[e1, e2| onFoo(e1, e2)]
component.addFooListener[onFoo(, )]