问题
如何重新绑定闭包的上下文
来源
最近遇见了一个闭包 它的内部调用了一些上下文未定义的方法 令人费解 …
抱着刨根问底的精神 愉♂悦地研究了一番 梳理清楚了其中的道理
代码
class Main { static main(String[] args) { new Main().callClosure { -> secretMethod() } } def callClosure(Closure clu) { new Sub(clu: clu).run() } } class Sub { Closure clu def secretMethod() { println "Sub: a ha!" } def run() { clu.delegate = this clu.call() } }
解释
注意到 Main
中出现的闭包中调用了 Main
中不存在的方法 secretMethod
显然不能成功运行
但是我们在 Sub
中实现了该方法 那么为了把这个闭包的上下文转移到 Sub
中去 就需要使用一些技术
clu.delgate = this
就是关键所在 在这里我们把 clu
闭包的上下文重新绑定到了新的上下文中 同时该闭包在新上下文中可以成功路由到之前未定义的神秘方法
大功告成
总结
隐含变量 | 作用 |
---|---|
it |
闭包的参数 类似 [:].each 的那种参数 是 Entry
|
delegate |
虽然意思是代理 但是其内涵更接近于闭包的上下文 |
this |
这里说的是闭包里的 this 就是闭包定义时的 this 语义 需要注意 static 限定下的闭包只能访问 this 的静态成员 |
owner |
delegate 的默认值 定义闭包时的上下文 但和 delegate 不同 它是只读的不能修改 显然如果 delegate 被替换 需要获取原来的上下文只能依靠它了 |
结束
说了这么多 owner
和 delegate
无非都在搬运原来的 this
而已 还有更多神秘的东西留待以后继续探索 例如多层闭包嵌套和静态闭包