【问题标题】:Groovy closure won't take two different classes that implement same interface?Groovy 闭包不会采用实现相同接口的两个不同类?
【发布时间】:2014-01-28 17:46:46
【问题描述】:

我正在通过 groovy 使用第三方 Java API,并且遇到了我编写的闭包的问题。问题似乎是闭包被编译为具有一个签名,该签名采用一个具体的类,而不是我想要它采用的接口。

所以,我们有两个类A 和B 实现了接口IInterface。

IInterface 有一个名为parent 的方法。 A 或B 中的任何对象的父对象都是B 中的对象。 (为简洁起见,我们将忽略到达这棵树的根的问题)。

如果我执行以下操作:

static def foo = { IInterface obj ->
    assert obj.parent() in IInterface
    foo(obj.parent())
}

然后用A中的一个对象调用它,然后当我期望它递归时它会失败,用

groovy.lang.MissingMethodException: No signature of method:
packagename.Runner$__clinit__closure5.foo() is applicable for argument types: (B)
values: ...

看起来foo() 已编译为采用A 而不是IInterface。我是否正确诊断了这一点?我错过了什么明显的东西吗?

为了完整起见,groovy --version 报告“Groovy 版本:2.1.6 JVM:1.7.0_09-icedtea 供应商:Oracle Corporation 操作系统:Linux”。

【问题讨论】:

  • 你确定B实现IInterface吗?
  • Show case A 和 B 表示 A 或 B 中的任何对象的父对象都是 B 中的对象。
  • 你能想出一个简短的例子来说明问题并且我们可以重复吗?
  • @Normal 指出了真正的问题——它与类型无关——它是递归不起作用。我已将他的答案标记为正确。

标签: groovy interface closures


【解决方案1】:

看起来你遇到了同样的问题 Recursion with closures in Groovy 2.1.9

试试这个:

def foo 
foo = { IInterface obj ->
    assert obj.parent() in IInterface
    foo(obj.parent())
}

【讨论】:

  • 谢谢 - 因为我使用的是静态闭包(它只是为了做一些快速的工作),您提供的链接中的第二种解决方案(将内部包装在另一个闭包中)有效。快速检查 groovyConsole 显示问题在 2.2.1 中仍然存在。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-01
  • 1970-01-01
  • 2015-03-23
  • 2016-07-23
  • 2014-10-25
  • 1970-01-01
相关资源
最近更新 更多