2012-11-14 45 views
1

这个问题,延伸着我以前的一个Groovy equivalent for Scala implicit parametersGroovy的等效斯卡拉隐含参数 - 扩展

不知道这是从以前的主题,以制定正确的方式,但无论如何..

我要寻找一个的方式来表达的常规是这样的:

// scala 
object A { 
    def doSomethingWith(implicit i:Int) = println ("Got "+i) 
} 
implicit var x = 5 

A.doSomethingWith(6) // Got 6 
A.doSomethingWith  // Got 5 

x = 0 
A.doSomethingWith  // Got 0 

在一般情况下,我想执行的逻辑块,而在它解决了根据所执行的“语境”有变数。 在scala中的隐含我似乎能够控制这种情况。我正在尝试寻找一种方法在groovy中做类似的事情。

基于从我试着喜欢这个方法,它的第一个问题的反馈:

// groovy 
class A { 
    static Closure getDoSomethingWith() {return { i = value -> println "Got $i" }} 
} 

value = 5 

A.doSomethingWith(6) // Got 6 
A.doSomethingWith() /* breaks with 
         Caught: groovy.lang.MissingPropertyException: 
         No such property: value for class: A */ 

现在,我通过常规闭合的定义就在http://groovy.codehaus.org/Closures+-+Formal+Definition

据我了解,吸气时被称为,失败发生为“编译器不能静态确定'价值'可用”

因此,有没有人对此方案的建议?干杯

回答

1

我设法通过检查脚本未解决的属性绑定到你想要的东西:

class A { 
    static Closure getDoSomethingWith() { { i = value -> println "Got $i" } } 
} 
A.metaClass.static.propertyMissing = { String prop -> binding[prop] } 

value = 5 


A.doSomethingWith 6 // Got 6 
A.doSomethingWith() // prints "Got 5" 
+0

意志,谢谢。您的解决方案仅在脚本中有效吗? – Ghiro

+0

是的,你需要在普通课堂上使用它? – Will

+0

是的,我喜欢。理想情况下,闭包的调用者不需要在闭包实例上“设置”任何东西,而只需确保上下文被初始化(本例中的'值'变量)。 – Ghiro

2

您也可以尝试改变返回闭幕的代表:

value = 5 

Closure clos = A.doSomethingWith 

// Set the closure delegate 
clos.delegate = [ value: value ] 

clos(6) // Got 6 
clos() // Got 5 
+0

顺便说一句,保持对映射的引用可以让你稍后改变它的值,并且它将在将来的闭包调用中有效。 –