我在A类上有一个静态闭包,它将调用委托给B类。但是,当在一个A实例上向A上的静态闭包发出一个call()时,我似乎无法访问实例属性。 A.不要太惊讶,因为我正在使用静态闭包。解决此问题的一种方法是将实例化的A设置为闭包委托。但是,我需要将B类作为静态闭包的委托。
无论如何我可以更改静态闭包的所有者,所以它指向实例化的A类而不是静态?并保持B作为代表?或者这不可能吗?
答案 0 :(得分:5)
你错了......你可以改变Closure
的所有者,但是它是多么可取,我不知道(因为设置者是私人的,所以必须有这样的理由)。无论如何,这是一个例子:
// Define a Person, with a closure to return a property
class Person {
String name
int age
Closure named = { -> "returned $name" }
}
// Define another Class with a similar property
class Furniture {
String name
int age
}
// Create our two objects
def tim = new Person( name:'tim', age:26 )
def chair = new Furniture( name:'chair', age:3 )
// Prints 'returned tim'
println tim.named()
// Add the closure from tim to the chair
chair.metaClass.named = tim.named
// Prints 'returned tim'
println chair.named()
// Change the owner to the chair instance
tim.named.@owner = chair
// prints 'returned chair'
println chair.named()
// prints 'returned chair'
println tim.named()
如您所见,我们可以将所有者从Person类更改为Furniture类。
然而,在实践中,您可能希望设置关闭而不是所有者的委托,但是没有您想要实现的示例,不可能说这是否是您想要的
答案 1 :(得分:0)
我发现覆盖所有者的最简单方法是重新声明闭包的实例:
def myClosure = { return this}
def myOwnClass = new String('aa')
assert myClosure.getClass().newInstance(myOwnClass,myOwnClass)() == myOwnClass
assert myClosure.getClass().newInstance(myOwnClass,myOwnClass)() == 'aa'
答案 2 :(得分:0)
给出一个(这里简化的)真实世界的例子来说明来自@tim_yates的好答案:
/** we want to use code completion and easy refactoring/debugging IDE capabilities
* (without "manual String code parsing") when we refer to very static project
* properties so working with them in a structured "enum-way" is useful */
@TypeChecked enum ProjectId {
foo( 'fooapp' )
bar( 'app-bar', { idAnt = 'proj.bar' } )
//bar( 'app-bar', { ProjectId it -> it.idAnt = 'proj.bar' } ) //(1)
// ...
;
// some static props of projects (may be many!)
String id // e.g. some standard repo name in a central dev store
String idAnt // e.g. some other id used in ANT scripts
Class<BaseEnvId> envIdClass = EnvIdCommon // default
// ...
/** the enum constructor */
ProjectId( String _id, Closure<Void> customizeDefaults = null ) {
id = _id
idAnt = id
if ( customizeDefaults ) {
// @owner-change so we do not have to use the clumsy/verbose syntax from (1)
// (above and below) otherwise the runtime(!) compiler would complain that
// ProjectId.idAnt (static field) does not exist (which is right)
customizeDefaults.@owner = this
customizeDefaults()
//customizeDefaults( this ) //(1)
}
}
}
答案 3 :(得分:-1)
答案是:这是不可能的。一个人无法改变关闭的所有者。