groovy.lang.MissingMethodException 'collect' 关闭 Groovy

groovy.lang.MissingMethodException for 'collect' closure in Groovy

我遇到了这个错误

No signature of method: ClassPath$_method_closure3.doCall() is applicable for argument types: ([AncestorOfFile]) values: [...values]
Possible solutions: doCall(File), findAll(), findAll(), isCase(java.lang.Object), isCase(java.lang.Object)

对于此代码

pageFiles = (someCollection as Collection<File>).collect {File file ->
    ...
    some logic
    ...
}

在内部变量没有类型声明“文件”的情况下工作得很好。我想我可以像这样使用类型声明来收集闭包,因为我使用类型化的集合。我做错了什么吗?

您需要double-check假设变量someCollection的类型为Collection<File>。看起来您希望该集合的每个元素都是 ru.naumen.modules.portal.types.File 类型,如果这是正确的,那么您可以将它应用于为 collect() 方法定义的闭包。

当您没有为该闭包定义 File file 参数时,您没有看到类似错误的原因是,在这种情况下,您定义的闭包接受任何类型的参数。让我通过示例向您展示这一点。

def someCollection = [[1,2,3,4,5]]

(someCollection as Collection<Integer>).collect { 
    // do something...
}

在此示例中,someCollection 的类型为 List<List<Integer>>。没有错误,代码似乎工作正常。但是如果你期望 collect 方法一个一个地获取每一个数字就不是了。相反,它获取整个数字列表。如果我们为该闭包声明所需类型的参数,则可以发现此问题:

def someCollection = [[1,2,3,4,5]]

(someCollection as Collection<Integer>).collect { Integer it ->
    // do something...
}

如果我们尝试 运行 这个例子,我们会得到一个类似于你的错误:

Caught: groovy.lang.MissingMethodException: No signature of method: test$_run_closure1.doCall() is applicable for argument types: (ArrayList) values: [[1, 2, 3, 4, 5]]
Possible solutions: doCall(java.lang.Integer), findAll(), findAll(), isCase(java.lang.Object), isCase(java.lang.Object)
groovy.lang.MissingMethodException: No signature of method: test$_run_closure1.doCall() is applicable for argument types: (ArrayList) values: [[1, 2, 3, 4, 5]]
Possible solutions: doCall(java.lang.Integer), findAll(), findAll(), isCase(java.lang.Object), isCase(java.lang.Object)
    at test.run(test.groovy:3)

要解决您的代码问题,您需要找出传递给没有类型定义的闭包的参数的类型。一种方法是打印 it.dump() 结果并查看值的类型。这就是我之前向您展示的示例的样子:

def someCollection = [[1,2,3,4,5]]

(someCollection as Collection<Integer>).collect {
    println it.dump()
}

输出:

<java.util.ArrayList@1c3e4a2 elementData=[1, 2, 3, 4, 5] size=5 modCount=1>

你会看到你期望的 ru.naumen.modules.portal.types.File 类型的值在现实中是不同的。也许这是一个文件列表,或者这是其他东西。然后如果你想让特定类型的闭包工作,你必须确保 someCollection 是现实中这些值的集合。