这是我在Java中的回调(future
是Mongo'} {/ 3}}:
future.register(new SingleResultCallback<ArrayList<Document>>() {
@Override
void onResult(ArrayList<Document> documents, MongoException e) {
//do something
}
})
使用Java 8,我可以使用Lambdas使它看起来像这样:
future.register((documents, e) -> {
//do something
});
纯。但是,我想在Groovy类中调用该Java方法。我知道Groovy当前不支持jdk8 lambda的语法,但是文档总是强调它们有闭包。如果我尝试在这种情况下使用闭包,则失败,因为闭包的类型为Closure
,而不是类型SingleResultCallback
。有没有办法让像一个不同类型的闭包?有没有其他方法可以很好地完成这项工作?我知道我可以使用第一个解决方案,但在一个groovy类中看起来很奇怪。
答案 0 :(得分:1)
使用Groovy的闭包语法:
future.register( { documents, e ->
//do something
});
如果register
方法重载存在歧义,则在闭包声明后可能需要as SingleResultCallback
:
future.register { documents, e -> } as SingleResultCallback
这是一个含糊不清的场景:
interface SingleResultCallback<T> {
def onResult(T result)
}
interface Callback { def onResult(obj) }
class Future {
void register(SingleResultCallback s) {
println "registered: ${s.onResult(10)}"
}
void register (Callback r) {
println "runnable=${r.onResult()}"
}
}
new Future().register { it ** 2 }
哪个失败了:
Caught: groovy.lang.GroovyRuntimeException:
Ambiguous method overloading for method Future#register.
Cannot resolve which method to invoke for [class Sam$_run_closure1] due
to overlapping prototypes between:
[interface Callback]
[interface SingleResultCallback]
如果SingleResultCallback
有多种方法,那么地图强制是处理它的好方法:
interface SingleResultCallback<T> {
def onResult(T result)
def onError
}
class Future {
def register(SingleResultCallback s) {
"registered: ${s.onResult(10)}"
}
}
assert new Future().register(
[onResult: { it ** 2 } ] as SingleResultCallback ) == "registered: 100"
答案 1 :(得分:0)
我知道问题提出已经有一段时间了,而且已经得到答复,但是我还要添加使用Groovy Closure作为回调的示例(更多信息请参见https://groovy-lang.org/closures.html)。
Groovy还支持将Closure作为对象,例如:
Closure callback = { println 'Done!' }
callback()
输出为:
Done!
上面只是另一个示例:
def callbackList(){
def list = ["RICE", "BEANS", "EGGS"]
iterableList(list, { elem ->
println elem
})
}
def iterableList(list, callback){
list.each {
callback(it)
}
}
输出为:
RICE
BEANS
EGGS