Groovy和Java Callbacks / Lambdas(带有类型的闭包)

时间:2014-06-18 19:43:04

标签: groovy lambda closures

这是我在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类中看起来很奇怪。

2 个答案:

答案 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