嵌套闭包分辨率在方法和属性之间有何不同?

时间:2014-12-23 20:21:12

标签: groovy closures

当闭包的resolveStrategy设置为DELEGATE_ONLYDELEGATE_FIRST时,在委托的方法和属性之间的嵌套闭包中,解析是不同的。例如,在下文中,x解析为f的委托(我期望的),但keySet()解析为g的委托。

​def g = {->
    def f = {
        {-> [x, keySet()]}()
    }

    f.resolveStrategy = Closure.DELEGATE_ONLY
    f.delegate = [x: 1, f: 0]

    f()
}      

g.delegate = [x: 0, g: 0]
g()

结果:[1, ['x', 'g']]

而没有嵌套的闭包

def g = {->
    def f = {
        [x, keySet()]
    }

    f.resolveStrategy = Closure.DELEGATE_ONLY
    f.delegate = [x: 1, f: 0]

    f()
}      

g.delegate = [x: 0, g: 0]
g()

结果:[1, ['x', 'f']]

这种行为是否需要并记录在某处?这是一个错误吗?

2 个答案:

答案 0 :(得分:0)

我相信这是一个错误。如果您更改Expando的地图,其行为会有所不同:

f = {
  g = {
    { -> keySet() }()
  }

  g.delegate = new Expando(a: 1000, b: 900, c: 800, keySet: { 'g keyset' })
  g.resolveStrategy = Closure.DELEGATE_ONLY
  g()

}

f.delegate = new Expando(a: 90, x: 9, y: 1, keySet: { 'f keyset' })

assert f() == 'g keyset'




f = {
  g = {
    { -> keySet() }()
  }

  g.delegate = [a: 1000, b: 900, c: 800]
  g.resolveStrategy = Closure.DELEGATE_ONLY
  g()

}

f.delegate = [a: 90, x: 9, y: 1]

assert f().toList() == ['a', 'b', 'c'] // fails :-(

也许正在填写JIRA

答案 1 :(得分:0)

我发现了一种解决方法,如果你永远不想落入所有者(即while($row = $result->fetch_assoc()) { $url = explode(" , ", $row["url"]); $urlcount = count($url); $i2 = 0; // reset $i2 here while ($i2<$urlcount) { echo $url[$i2]."<br>"; $i2++; } } ):你可以将委托和所有者都设置为相同的值:

DELEGATE_ONLY

结果:def g = {-> def f = { {-> [x, keySet()]}() } def d = [x: 1, f: 0] f = f.rehydrate(d, d, f.thisObject) f() } g.delegate = [x: 0, g: 0] g()

请注意[1, ["x", "f"]]不起作用:虽然没有错误,但似乎是无操作。您必须使用f.owner = d