问题描述:

I'd like to call a closure with a delegate parameter to override or shadow the calling context. But the following example prints prints "outside" where I expect "inside".

What am I doing wrong?

def f(String a){

def v = { return a }

v.delegate = [a:"inside"]

// Makes no difference:

// v.resolveStrategy = Closure.DELEGATE_FIRST

println(v.call())

}

f("outside")

网友答案:

I believe the issue is that when the closure is declared inside the function, it 'closes' round the known values in the method (a), so that value becomes effectively hard-coded into the closure (it never hits the delegate to find the unknown value as it is known to the Closure).

If you move the closure v definition outside of the function f, then it works:

v = { return a }

def f(String a){
  v.delegate = [a:"inside"]
  println(v.call())
}

f("outside")
网友答案:

Other option is to use getProperty('a') instead of directly using a as this forces the use of the delegate to retrieve the value of a.

网友答案:

Can also be done by referring the delegate in the closure. For v as a closure, a does not make any sense (equivalent to use of ExpandoMetaClass)

def f(String a){
  def v = { delegate.a }
  v.delegate = [a:"inside"]

  println v()
}

f("outside")
相关阅读:
Top