我有一个这样的课
class SomeClass () {
Closure instClos
SomeClass (Closure clos) { instClos = clos} //constructor
def call() {instClos()}
}
我想要做的是做这样的隐式类构造函数
SomeClass myInst = {println "hello there}
myInst()
但这不起作用并抛出强制转换异常 . 你可以通过在封闭处写[]来调用构造函数来完成这项工作 . 但它不漂亮
SomeClass myInst = [{println "hello there}] // or myInst = new ({println "hello there}
myInst()
是否有一种通过赋值创建对象的好方法,并将该闭包自动存储在创建的类实例上?
我觉得我在这里缺少一些groovy语法,可以对此进行排序(如果我可以避免,我不想扩展Closure)
根据目前提供的输入,我提供了一个扩展脚本来显示各种选项 . 我尝试向Closure添加一个asType闭包并尝试将作为SomeClass调用 - 但是如果我尝试从未调用asType,那么当你尝试强制时,groovy必须使用另一种机制
class SomeClass {
Closure instClos
SomeClass (Closure clos) {
println "\tSomeClass constructor: Will constructor called"
instClos = clos
}
def call() {
println "\tSomeClass.call: calling closure "
return (instClos() + "!")
}
SomeClass asType (Closure clos) {
new SomeClass (instClos: clos)
}
}
//this will call the map constructor - needs to be explicitly provided
SomeClass me = [{println "map style construction"; "echo"}]
assert me() == "echo!"
//use new to get class instance with constructor
me = new SomeClass ({println "new SomeClass () construction"; "echo"})
assert me() == "echo!"
//using layered closure approach - doesnt read well though
def someClos = {new SomeClass(it)}
def c = someClos {println "trying layered closure ";"echo"}
assert c() == "echo!"
//extending the Closure class to add a method
ExpandoMetaClass.enableGlobally()
Closure.metaClass.some = {
if (it == SomeClass) {
new SomeClass (delegate)
}
}
//this will call .some() on closure
me = {println "hello will using .some() "; "echo"}.some ( SomeClass)
assert me() == "echo!"
2 回答
无论如何我都不知道自动强制关闭 . 即使groovy有closure coercion,它的工作方式是更改闭包's type, but it'仍然是一个闭包,并且不是分层的 . 一些想法:
1.构造函数
2. Map 构造函数
3.关闭元编程
(需要enableGlobally())
4.另一个封闭分层
5.覆盖Closure的asType
如果您的设计具有足够的灵活性,那么您只需要一个方法,然后您可以将其指定为接口:
Groovy很久以前就预料到了Java 8使用
@FunctionalInterface
注释形式化的情况 . 如果将Groovy Closure分配给接口类型的变量或形式参数,其中接口只有一个方法(如上面定义的SomeClass
),则Groovy编译器会将闭包强制转换为该接口的实例 . 因此,给定上面的接口声明,以下代码:打印“你好” .