是否有一种干净的方法可以在Groovy中指定Closure参数类型?

时间:2019-10-31 10:58:15

标签: groovy annotations closures

我知道@ClosureParams注释。它似乎仅涵盖更复杂的用例。我正在注释闭包部分中寻找类似described here的东西。与以下代码段相似:

void doSomething(MyType src, @ClosureParams(MyType) Closure cl) { ... }

不幸的是,此示例不再能与最新的groovy版本一起编译(目前我在2.5.8上)。我知道我可以做到:

void doSomething(MyType src, @ClosureParams(FirstParam) Closure cl) { ... }

我的用例除了闭包本身外没有其他参数:

void doSomething(@ClosureParams(/* how? */) Closure cl) { ... }

我可以像这样破解它:

void doSomething(@ClosureParams(SecondParam) Closure cl, MyType ignore = null) { ... }

这还远远不够干净,不是吗?

我也可以去

void doSomething(@ClosureParams(value = SimpleType, options = ['com.somepackage.MyType']) Closure cl) { ... }

这不仅丑陋而且嘈杂,而且将类型指定为字符串还会阻止某些IDE功能正常工作。例如,MyType重构,重命名或搜索用法将不在此处显示。

我想,没有任何更干净的方法可以实现此目的,因此可以将类型指定为类型,而不是字符串,并且没有多余的参数,是吗?

像上面的CédricChampeau 最初在上面链接的博客中所发布的那样,是理想的选择。在我的情况下看起来像这样:

void doSomething(@ClosureParams(MyType) Closure cl) { ... }

1 个答案:

答案 0 :(得分:1)

您可能要考虑使用FromAbstractTypeMethods签名提示而不是SimpleType。它使用起来很冗长,但是它为您带来SimpleType提示类所缺少的好处-您可以轻松地重构签名类中定义的类型,还可以找到签名提示中使用的类的用法。主要缺点是您需要为每个闭包签名提示创建其他抽象类,并且将包含签名作为抽象方法的类的名称定义为常量字符串(SimpleType签名也存在相同的问题提示。)但是,只有一个参数doSomething方法,而没有添加第二个null参数只是为了能够使用SecondParam签名提示。

package com.example

import groovy.transform.Immutable
import groovy.transform.stc.ClosureParams
import groovy.transform.stc.FromAbstractTypeMethods

class MyClass {
    static void doSomething(@ClosureParams(value = FromAbstractTypeMethods, options = ["com.example.MySignatures"]) Closure cl) {
        cl.call()
    }

    static void main(String[] args) {
        doSomething {
            println it.name
        }
    }
}

@Immutable
class MyType {
    String name
    int x
    int y
}

abstract class MySignatures {
    abstract void firstSignature(MyType myType)
    abstract void secondSignature(MyType myType, String str)
}

enter image description here

我猜想删除了简单干净的@ClosureParams(String)变体来满足其他更复杂的用例。 ClosureParams注释的API是固定的,并且将options限制为字符串数组。也许可以通过实现自己的ClosureSignatureHint来实现-我几个月前已经尝试过,但是我无法让IntelliJ IDEA使用我的自定义类来提供签名提示。