有没有一种干净的方法来在Groovy中指定Closure参数类型?

top*_*opr 5 groovy closures annotations

我知道@ClosureParams注解。它似乎仅涵盖更复杂的用例。我正在寻找像这里所描述注解关闭部分。与以下代码段相似:

void doSomething(MyType src, @ClosureParams(MyType) Closure cl) { ... }
Run Code Online (Sandbox Code Playgroud)

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

void doSomething(MyType src, @ClosureParams(FirstParam) Closure cl) { ... }
Run Code Online (Sandbox Code Playgroud)

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

void doSomething(@ClosureParams(/* how? */) Closure cl) { ... }
Run Code Online (Sandbox Code Playgroud)

我可以像这样修改它:

void doSomething(@ClosureParams(SecondParam) Closure cl, MyType ignore = null) { ... }
Run Code Online (Sandbox Code Playgroud)

距离还很远,不是吗?

我也可以去:

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

它不仅丑陋且嘈杂,而且将类型指定为字符串会阻止某些IDE功能正常工作。例如MyType,此处不会选择refactor-rename或搜索用法。

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

CédricChampeau最初在上面链接的博客文章中所发布的东西是理想的。在我的情况下看起来像:

void doSomething(@ClosureParams(MyType) Closure cl) { ... }
Run Code Online (Sandbox Code Playgroud)

Szy*_*iak 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)
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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