Groovy闭包-缺少属性 [英] Groovy closures - Missing property

查看:143
本文介绍了Groovy闭包-缺少属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将jenkins管道编写为脚本之前,尝试学习groovy闭包.

Trying to learn groovy closures, before writing jenkins pipeline as script.

下面的代码:

def scores = [72,29,32,44,56]

def analyse(closure){
    closure(scores)
}

def firstScore(array){
    return array[0]
}

analyse(firstScore)


给出错误:


gives error:

groovy.lang.MissingPropertyException: No such property: firstScore for class: groovy.lang.Binding
    at groovy.lang.Binding.getVariable(Binding.java:63)


如何解决此错误?


How to resolve this error?

推荐答案

您会看到此错误,因为firstScore是代码示例中的方法而不是闭包.您可以将firstScore定义从方法更改为闭包,例如

You see this error because firstScore is a method and not a closure in your code example. You can either change firstScore definition from method to closure, e.g.

def firstScore = { array ->
    return array[0]
}

或者您可以使用Groovy的方法指针运算符,用于将方法转换为闭包.在这种情况下,您将必须通过以下方式调用analyze方法:

or you can use Groovy's method pointer operator that converts a method to a closure. In this case you would have to invoke analyze method in the following way:

analyze(this.&firstScore)

除此之外,您的Groovy脚本仍将失败.您尝试访问analyze方法内的scores.您需要知道,脚本中定义的任何方法都会自动提升为类级别的方法(每个Groovy脚本都编译为扩展groovy.lang.Script类的类).您在Groovy脚本主体中定义的所有其他表达式和语句都是Script.run()方法的一部分,它们在本地范围内.因此,当方法Script.analyze()被调用时,它将抱怨不存在的属性scores,因为scoresScript.run()方法的本地范围内.要解决此问题,您可以使用@groovy.transform.Field批注注释scores变量,该批注将局部变量转换为类级别的属性-在这种情况下,可以从任何方法访问scores.

Other than that - your Groovy script will still fail. You try to access scores inside the analyze method. You need to know that any method defined in a script gets automatically promoted to be a class level method (every Groovy script compiles to a class that extends groovy.lang.Script class). All other expressions and statements you define in the Groovy script body are a part of the Script.run() method and they are in the local scope. So when the method Script.analyze() gets invoked, it will complain about non-existing property scores, because scores is in the local scope of Script.run() method. To fix it you can annotate scores variable with the @groovy.transform.Field annotation that converts local variable to a class level property - in this case scores can be accessed from any method.

下面您可以找到策划脚本的示例:

Below you can find an example of the curated script:

import groovy.transform.Field

@Field
def scores = [72,29,32,44,56]

def analyse(closure){
    closure(scores)
}

def firstScore(array){
    return array[0]
}

println analyse(this.&firstScore)

输出:

72

最后但并非最不重要的一点.阅读 可扩展管道代码的最佳做法" 博客文章.它解释了编写Jenkins管道代码的最佳实践.另外,您需要意识到以下事实:流水线代码是在Groovy CPS模式下执行的,该模式

And last but not least. Read "Best Practices for Scalable Pipeline Code" blog post carefully. It explains best practices in writing Jenkins pipeline code. Also, you need to be aware of the fact, that pipeline code gets executed in Groovy CPS mode, which has a bunch of limitations. Knowing them will help you solve problems you will definitely face after jumping from Groovy to a pipeline code.

这篇关于Groovy闭包-缺少属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆