使用 expando 元类添加 curried 闭包作为静态属性会丢失默认参数值
Posted
技术标签:
【中文标题】使用 expando 元类添加 curried 闭包作为静态属性会丢失默认参数值【英文标题】:Adding curried closure as static property with expando metaclass loses default parameter value 【发布时间】:2012-07-20 02:42:06 【问题描述】:我在 Groovy 1.8.6 和 2.0.0 中都遇到过这种情况。
所以这些场景都按预期工作:
def ay = one, two=[:] -> [one, two]
def be = one, two, three=[:] -> [one,two,three]
def ayprime = ay.curry('PRIME')
def beprime = be.curry('PRIME')
def beprimer = be.curry('PRIME', 'PRIMER')
assert ay(1,2) == [1,2]
assert ay(1) == [1,[:]]
assert be(1,2,3) == [1,2,3]
assert be(1,2) == [1,2,[:]]
assert ayprime(1) == ['PRIME', 1]
assert ayprime() == ['PRIME', [:]]
assert beprime(1,2) == ['PRIME', 1, 2]
assert beprime(1) == ['PRIME', 1, [:]]
assert beprimer(1) == ['PRIME', 'PRIMER', 1]
assert beprimer() == ['PRIME', 'PRIMER', [:]]
这样:
class Klass
static def smethod = one, two=[:] -> [one, two]
assert Klass.smethod(1,2) == [1, 2]
assert Klass.smethod(1) == [1, [:]]
这也可以正常工作:
Klass.metaClass.static.aymethod << ay
assert Klass.aymethod(1) == [1, [:]]
uncurried 闭包的默认参数在分配给Klass
之后仍然存在。
但是,这个失败了:
Klass.metaClass.static.ayprimemethod << ayprime
assert Klass.ayprimemethod() == ['PRIME', [:]]
因此:
assert Klass.ayprimemethod() == ['PRIME', [:]]
| |
[PRIME, null] false
同样,这失败了:
Klass.metaClass.static.beprimermethod << beprimer
assert Klass.beprimermethod() == ['PRIME', 'PRIMER', [:]]
因此:
assert Klass.beprimermethod() == ['PRIME', 'PRIMER', [:]]
| |
| false
[PRIME, PRIMER, null]
使用柯里化闭包,默认参数值直接起作用,但当闭包被分配为Klass
的静态成员时会丢失。
这似乎像一个错误。我在任何地方都找不到这种行为。我错过了什么吗?
【问题讨论】:
我看到了同样的行为。我还将它作为类实例方法进行了测试(因此可以通过Klass.metaClass.ayprimemethod << ayprime; assert new Klass().ayprimemethod() == ['PRIME', [:]]
对其进行测试),并发现了同样的问题。看起来你应该file a bug in JIRA。
完成。 jira.codehaus.org/browse/GROOVY-5621
感谢currying的解释:)
【参考方案1】:
如果问题仍然困扰您,我认为这可能是一种解决方法,直到它在 groovy 主干中得到修复。咖喱东西的python方式:
def ayprime = x -> x ? ay('PRIME', x) : ay('PRIME')
def beprime = be.curry('PRIME')
def beprimer = x -> x ? be('PRIME', 'PRIMER', x) : be('PRIME', 'PRIMER')
【讨论】:
以上是关于使用 expando 元类添加 curried 闭包作为静态属性会丢失默认参数值的主要内容,如果未能解决你的问题,请参考以下文章
使用 WCF Web Api 大量返回动态类型/Expandos?
如何在 Google App Engine expando 类中创建动态字段?