Groovy:定义没有“def”的变量与使用锚定有什么区别?

Ita*_*not 5 groovy scope

我现在正在学习 Groovy,遇到了一些我不明白的事情,希望您能够提供一些帮助。

关于以下示例:

import groovy.transform.Field
  @Field List awe = [1, 2, 3]
  def awesum() { awe.sum() }
  assert awesum() == 6
Run Code Online (Sandbox Code Playgroud)

我知道这种锚定允许我将 awe 变量的范围从在脚本的方法级别运行更改为脚本的类级别。

但后来我想到了使用 def 定义变量与不使用 def 定义变量之间的区别,例如:

def var = "foo"
Run Code Online (Sandbox Code Playgroud)

var = "foo"
Run Code Online (Sandbox Code Playgroud)

据我了解,这两个示例之间的差异是范围的差异。当我在 Groovy 脚本中为没有“def”或其他类型的变量分配值时,它会添加到“绑定”(脚本的全局变量)中。这意味着可以从脚本中的所有函数访问它。

因此,考虑到“@Field”和不使用“def”定义变量并遵循这一思路,我将示例代码更改为:

import groovy.transform.Field
  awe = [1, 2, 3]
  def awesum() { awe.sum() }
  assert awesum() == 6
Run Code Online (Sandbox Code Playgroud)

它有效。

所以我的问题是为什么要使用锚定?如果您可以通过定义不带“def”的变量来实现相同的目标?

Mar*_*ber 3

你们没有实现相同的目标- 请参阅下面的差异

import groovy.transform.Field
awe = [1, 2, 3]
def awesum() { awe.sum() }
assert awesum() == 6
awe = 1
Run Code Online (Sandbox Code Playgroud)

工作正常,因为变量是动态类型的。相反这会失败

import groovy.transform.Field
@Field List awe = [1, 2, 3]
def awesum() { awe.sum() }
assert awesum() == 6
awe = 1
Run Code Online (Sandbox Code Playgroud)

由于变量是强类型的(java.util.ArrayList)

Caught: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '1' with class 'java.lang.Integer' to class 'java.util.List'
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '1' with class 'java.lang.Integer' to class 'java.util.List'
        at FieldTest1.run(FieldTest1.groovy:5)
Run Code Online (Sandbox Code Playgroud)