Groovy - 检查参数是否为函数

5
在JavaScript中,这是我检查函数参数是否为函数的方法:
function foo ( p ) {
    if ( typeof p === 'function' ) {
        p();
    }
    // ....
}

我该如何在Groovy中实现相同的功能?
3个回答

12

Groovy让闭包成为一等公民。每个闭包都扩展了抽象类groovy.lang.Closure<V>,如果参数类型未定义,您可以使用instanceof来检查传递给方法的参数是否是闭包。就像这样:

def closure = {
    println "Hello!"
}

def foo(p) {
    if (p instanceof Closure) {
        p()
    }
}

foo(closure)

运行此脚本会生成输出:
Hello!

使用具体参数类型

Groovy允许您(实际上值得这样做)定义方法参数的类型。您可以要求调用者传递一个闭包,而不是检查p是否为闭包。考虑以下示例:

def closure = {
    println "Hello!"
}

def foo2(Closure cl) {
    cl()
}

foo2(closure)
foo2("I'm not a closure")

第一次调用将会执行闭包的操作(打印"Hello!"),但第二次调用将抛出异常:

Hello!
Caught: groovy.lang.MissingMethodException: No signature of method: test.foo2() is applicable for argument types: (java.lang.String) values: [I'm not a closure]
Possible solutions: foo2(groovy.lang.Closure), foo(java.lang.Object), find(), find(groovy.lang.Closure), wait(), run()
groovy.lang.MissingMethodException: No signature of method: test.foo2() is applicable for argument types: (java.lang.String) values: [I'm not a closure]
Possible solutions: foo2(groovy.lang.Closure), foo(java.lang.Object), find(), find(groovy.lang.Closure), wait(), run()
    at test.run(test.groovy:18)

始终将代码做成类型安全的是一个好习惯,这样您就不必担心作为参数传递的值是否是您所期望的类型。


我认为你也可以选择 Runnable - cfrick
嗯,我不会这么说。Closure<V>返回V,因此如果我们期望从函数/闭包中返回一些东西,那么使用Runnable就不合适。 - Szymon Stepniak
我的意思是,Runnable 实例和 p.run() 可能更加通用。但是,确实没有返回值。 - cfrick

5
在Groovy中,您需要检查p是否是Closureinstanceof
def foo(p) {
    if (p instanceof Closure) {
        p()
    } else {
        println "p is $p and not a Closure"
    }
}

foo { -> println "I'm a closure" }
foo('tim')

输出:

I'm a closure
p is tim and not a Closure

0
def eval = {o->([o].grep(Closure).find()?:{o})()}

println eval('foo')
println eval({->'bar'})
println eval{'baz'}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接