使用def和不使用def定义变量有什么区别?

时间:2016-09-15 15:20:50

标签: jenkins groovy jenkins-pipeline

关于Jenkins DSL,有什么区别:

def cwd = pwd()

cwd = pwd()

2 个答案:

答案 0 :(得分:7)

这是范围的差异。当您为没有“def”或其他类型的变量赋值时,在Groovy脚本中,它会添加到“绑定”,即脚本的全局变量。这意味着可以从脚本中的所有函数访问它。如果您在脚本顶部定义了变量,那就很好了。

如果多个线程对脚本起作用,您可能会遇到意外行为。

def a = {
  x = 1
  println x
}
def b = {
  x = 2
  println x
}
new Thread(a).start()
new Thread(b).start()

......可以产生两个,两个二,或混合。

相反,使用“def”会产生一个局部变量:

def a = {
  def x = 1
  println x
}
def b = {
  def x = 2
  println x
}
new Thread(a).start()
new Thread(b).start()

...将始终以任意顺序打印1和2。

答案 1 :(得分:1)

这是一个很好的问题,但它更像是一个Groovy问题。

根据我的理解,定义一个没有def关键字的变量可以在脚本中运行,但如果你在类方法中则不行。此blog post的示例:

class MyTest {
    def testMethod() {
        y = 3
        println y
    }    
}

t = new MyTest()
t.testMethod()

变量t的定义没有问题,但y定义会引发异常。

这意味着在我们的上下文(Jenkins管道)中,您始终可以在没有def关键字的情况下定义变量,因为您始终在脚本上下文中,并且您的变量将绑定到脚本。但是,我认为使用def关键字是一个好习惯,因为它会告诉您何时实例化变量,并且还可以避免重复变量定义的一些问题(如果使用def定义它们如果你定义了两次相同的变量,至少编译将失败。

最后,来自Groovy documentation

  

在Groovy中使用def时,实际的类型持有者是Object(所以你可以   将任何对象分配给使用def定义的变量,并返回任何类型   如果声明方法返回def),则返回对象。

因此,您可能希望具体并指定要定义的变量类型。在您的情况下,您可以将cwd定义为:

String cwd = pwd()

禁止你做以下事情:

def cwd = pwd()
cwd = 1000     // Valid code

String cwd2 = pwd()
cwd2 = 1000    // Will fail compilation