2011-04-15 27 views
9

我想更清楚地了解我的关于他们的参数类型的闭包。所以,我喜欢写东西Groovy中输入参数的关闭

List<Y> myCollect(List<X> list, Closure<X,Y> clos) { ... } 

我知道,Groovy中不会使用该类型的信息,但Groovy的++可以在编译时使用它。这可以实现(除了将其纳入评论)?

更新: 标题可能听起来有误导性,但我认为上面的例子会使它更清晰。我有兴趣指定一个闭包的类型,它是一些函数的参数。假设,我想重新定义内置的collect。所以我有兴趣写myCollect,而不是写在clos。我想实现的是编译时错误

myCollect(['a', 'ab'], { it/2 }) // compile error 
myCollect(['a', 'ab'], { it.size() }) // OK 
+1

在类型Closure 中,V表示闭包的返回值,而不是其参数。因此,由于无法返回两个值,因此设置Closure 是没有意义的。 – 2013-07-26 01:16:09

+0

我的意思是'Closure '接受一个'X'作为输入并返回'Y'。所以它可以应用于'List '的项目。我更新了函数的返回类型。 – 2013-07-26 08:57:44

回答

6

您可以定义闭包参数的类型,但上面显示的语法不正确。这里是不带参数类型的闭包:

def concatenate = {arg1, arg2 -> 
    return arg1 + arg2 
} 

这里是一样的封闭与参数类型

def concatenate = {String arg1, String arg2 -> 
    return arg1 + arg2 
} 

我知道,Groovy中不会使用该类型的信息,但Groovy的++可以使用它在编译时。

Groovy确实做了一些编译时类型检查,但没有Groovy ++(或Java)那么多。即使在编译时不使用类型信息,它也会在运行时检查,并且作为文档形式也很有价值。

+0

请看我的更新。你的'concatenate'是什么类型?它是'Closure '?或者是什么? – 2011-04-18 17:07:09

+0

我接受这个答案并不是因为我很满意,但这是唯一的一个:(也许,我的问题不够清楚。 – 2011-07-22 10:35:05

0

我认为你不再使用Groovy ++,但即使你是这样也可能工作。这当然适用于静态类型的Groovy 2.x的

interface Z { 
    void callback(X x, Y y) 
} 

List<Y> myCollect(List<X> list, Z clos) { 
    ... 

    clos.callback(x, y) 
} 

来电,然后与正常调用它:

List<Y> object.myConnect(list) { X x, Y y -> 
} 

如果你离开一个参数并有@CompileStatic,编译器拿起失踪PARAMS或不好的类型。

这是可行的,因为1方法接口相当于Groovy中的闭包。