使用具有不同返回类型的Closure参数重载Groovy中的方法

时间:2016-01-15 12:39:07

标签: grails groovy

在我的工作需要的情况下,我对Groovy非常熟练,但没有OOP的背景意味着有些事情仍然无法实现,所以如果有些措辞有点偏离,请道歉(随意编辑)如果你能让问题更清楚的话。)

我试图创建一个重载方法,其中签名(理想情况下)仅在单个Closure参数的返回类型上有所不同。 Closure包含一个方法调用,它返回一个ItemResponse或ListResponse对象,这两个对象都可以包含任何类型的对象/对象(这是我想要推断的类型)。

以下代码是我尝试实现的简化版本 - 一种错误处理方法,它接受对服务调用的引用,安全地尝试解析它,并从响应中返回项目/项目合适:

public <T> T testMethod(Closure<ItemResponse<T>> testCall) {
    testCall.call().item as T
}

public <T> List<T> testMethod(Closure<ListResponse<T>> testCall) {
    testCall.call().items as T
}

显然这不起作用,但有没有可以达到预期结果的替代方法/解决方法?

2 个答案:

答案 0 :(得分:1)

  

我试图创建一个签名的重载方法   (理想情况下)仅在单个Closure的返回类型上有所不同   参数。

您不能这样做,因为返回类型不是方法签名的一部分。例如,以下内容无效:

class Demo {
    int doit() {}
    String doit() {}
}

答案 1 :(得分:1)

正如您自己和@jeffscottbrown所提到的,您不能拥有两个具有相同参数但返回值不同的方法。我在这里看到的解决方法是使用回调闭包。您testMethod的返回值将默认为Object,并且您将提供一个“解包器”,它将在闭包调用后提取(提取itemitems)。在GroovyConsole中试试这个:

class ValueHolder <T> {
    T value
}

Closure<List<Integer>> c = {
    [1]
}

Closure<ValueHolder<String>> d = {
    new ValueHolder(value:'hello world')
}

Closure liu = {List l ->
    l.first()
}

Closure vhsu = {ValueHolder vh ->
    vh.value
}

// this is the generic method
public <T> Object testMethod(Closure<T> testCall, Closure<T> unwrapper) {
    unwrapper(testCall.call()) as T
}

println testMethod(c, liu)
println testMethod(d, vhsu)

它适用于列表或值持有者。