简体   繁体   English

Gradle/Groovy 闭包范围混淆

[英]Gradle/Groovy closure scope confusion

I'm new to Gradle/Groovy and am running into issues with variable name resolution in nested closures.我是 Gradle/Groovy 的新手,并且遇到了嵌套闭包中变量名称解析的问题。 I have a custom task class that defines some properties and I am instantiating potentially multiple tasks of that type using a closure.我有一个自定义任务类,它定义了一些属性,并且我正在使用闭包实例化该类型的多个潜在任务。 This closure defines a variable named the same as one of the properties in the custom task class and I am running into some odd behavior which seems to go against what is defined in the Groovy language guide.这个闭包定义了一个与自定义任务类中的一个属性名称相同的变量,我遇到了一些奇怪的行为,这似乎与 Groovy 语言指南中定义的内容背道而驰。 Could someone please answer the questions in the code below?有人可以回答下面代码中的问题吗?

class Something extends DefaultTask {
    def thing = "a"
}
/*
def thing = "b" // produces the error message:
                // > Could not find method b() for arguments [build_63hfhkn4xq8gcqdsf98mf9qak$_run_closure1@70805a56] on root project 'gradle-test'.
                // ...why?
*/
(1..1).each {
    def thing = "c"
    task ("someTask${it}", type: Something) {
        println resolveStrategy == Closure.DELEGATE_FIRST // prints "true"
        println delegate.class // prints "class Something_Decorated"
        println thing // prints "c" shouldn't this be "a" since it's using DELEGATE_FIRST?
        /*
        println owner.thing // produces the error message:
                            // > Could not find property 'thing' on root project 'gradle-test'
                            // shouldn't the "owner" of this closure be the enclosing closure?
                            // in that case shouldn't this resolve to "c"
        */
    }
}


EDIT: For some reason after changing all of the def into String and then back into def I can no longer replicate the def thing = "b" line producing that weird error编辑:出于某种原因,在将所有def更改为String然后返回def我无法再复制def thing = "b"行产生那个奇怪的错误

The code prints c because the variable named thing is declared within the lexical scope of the closure.代码打印c是因为名为thing的变量是在闭包的词法范围内声明的。 It means that closure can just use the value of this variable.这意味着闭包只能使用这个变量的值。 What will work:什么会起作用:

  1. Renaming the thing variable defined in the closure.重命名闭包中定义的thing变量。

  2. Explicitly referring to thing via delegate :通过delegate明确指代thing

    println delegate.thing

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM