我正试图做一些类似的事情
def myFunc(Closure config) {
def var1
def var2
config()
println var1, var2
}
myFunc {
var1 = "hello"
var2 = "world"
}
有没有办法做到这一点?委托只适用于类字段,而不适用于本地变量。
binding
对象,它持有所有不是变量、字段等的绑定。
在您的情况下会发生以下情况:
myFunc {
var1 = "hello"
var2 = "world"
}
当执行此闭包时,它将var1
和var2
添加到具有相应值的binding
中。执行myFunc
时:
def myFunc(Closure config) {
def var1
def var2
config()
println var1
println var2
}
它不使用binding
来读取var1
和var2
的值,因为在当前范围内,这两个变量都存在,这就是的原因
null
null
打印。
但如果你把var1
和var2
在config()
之后的阅读方式改成这样:
def myFunc(Closure config) {
def var1
def var2
config()
println binding.getVariable("var1") ?: var1
println binding.getVariable("var2") ?: var2
}
您将明确检查config()
是否将var1
和var2
添加到binding
中,如果为true,您将读取由执行的闭包修改的值。否则,您将读取var1
和var2
的本地默认值。
hello
world
这类似于从myFunc
中删除局部变量并调用类似于的闭包
def myFunc(Closure config) {
config()
println var1
println var2
}
但在这种情况下,您仅指binding
,在该过程中没有涉及局部变量的位置。我猜你必须处理现有的局部变量,而不能只是删除它们——在这种情况下,明确读取binding
或局部变量是处理它的最佳方式
Gradle案例
如果在build.gradle
脚本中遇到这种情况,您可以使用一种流行的方法来使用映射对象委托,因此闭包中使用的所有变量都会自动分配为映射属性。考虑以下示例:
def myFunc(Closure config) {
def var1
def var2
def map = [:]
config.delegate = map
config.resolveStrategy = Closure.DELEGATE_FIRST
config()
println map.getOrDefault('var1', var1)
println map.getOrDefault('var2', var2)
}
task hello {
doLast {
myFunc {
var1 = "hello"
var2 = "world"
}
}
}
在这种情况下,在给定闭包的情况下运行myFunc
以在委托映射对象上分配var1
和var2
属性结束。它为我们提供了使用map.getOrDefault(key,default)
方法检索带有闭包的值集或使用默认局部变量值的机会。
您是否尝试删除如下所示的变量?
def myFunc(Closure config) {
config()
println var1
println var2
}
myFunc {
var1 = "hello"
var2 = "world"
}