Groovy';def&x27;Eclipse中的关键字和范围问题

Groovy';def&x27;Eclipse中的关键字和范围问题,eclipse,groovy,scope,Eclipse,Groovy,Scope,我正在学习groovy教程,其中有一段代码如下: def fruit = ["apple", "orange" , "pear"] //list def likeIt = { String fruit -> println "I like " + fruit + "s" } //closure fruit.each(likeIt) Eclipse在闭包定义行报告错误: 行断点:SimpleCloseResTest [第27行]当前范围已存在 包含名为fruit的变量 @第27

我正在学习groovy教程,其中有一段代码如下:

def fruit = ["apple", "orange" , "pear"]    //list
def likeIt = { String fruit -> println "I like " + fruit + "s" }    //closure
fruit.each(likeIt)
Eclipse在闭包定义行报告错误:

行断点:SimpleCloseResTest [第27行]当前范围已存在 包含名为fruit的变量 @第27行第14列

如果我在defruit中省略了def,Eclipse不会抱怨,代码运行良好

有人能解释一下这两种情况下示波器的情况吗

谢谢。

第二行

串果

第二行再次使用了相同的变量名'fruit'

串果


再次使用了相同的变量名“fruit”

字符串fruit不应与def fruit具有相同的名称。(首先定义一个列表,然后定义一个同名字符串)

在第二种情况下,您使用def a posteriori定义变量的类型,因此它可以工作,但据我所知,这不是一个好的实践


我认为你甚至不需要写->。groovy手册说,“如果闭包定义使用的参数少于两个,->token是可选的,可能会被忽略”,这里就是这种情况。

字符串fruit不应该与def fruit具有相同的名称。(首先定义一个列表,然后定义一个同名字符串)

在第二种情况下,您使用def a posteriori定义变量的类型,因此它可以工作,但据我所知,这不是一个好的实践


我认为你甚至不需要写->。groovy手册说,“如果闭包定义使用的参数少于两个,->token是可选的,可以省略”,这里就是这种情况。

首先对groovy脚本进行概述:

// file: SomeScript.groovy
x = 1
def x = 2
println x
println this.x
其大致汇编如下:

class SomeScript extends groovy.lang.Script {
  def x
  def run() {
    x = 1
    def x = 2
    println x // 2
    println this.x // 1
  }
}
在groovy脚本中(粗略地说,是一个没有类声明的文件),为未定义的变量赋值被解释为字段赋值

您的示例尝试使用名为
fruit
的参数定义闭包
如果使用
def
关键字定义了
fruit
,则会收到一条错误消息,因为该名称已被视为局部变量,并且不能复制局部变量名称。
当您不使用
def
关键字时,实际上是在将值分配给为脚本生成的类的字段,因此名称
fruit
可以重新定义为局部变量

关于作用域,它很像java…
在该示例中,您可以看到
x
首先定义为一个字段,然后定义为
run()
方法的局部变量。这没有什么问题,您可以访问变量和字段。
但一旦定义了局部变量,就无法创建重复项

编辑--
在任何人误解我之前,我必须补充这一点:翻译与此不完全相同(因此“大致”)。您可以向脚本的绑定添加一个值,而不是一个字段,就像命令行脚本的
args
或Groovlet的
request
session
response

但这是一个更长的故事……
好吧,如果你真的想知道,再问一次,我会更好地解释

编辑2-- 我不能就这样离开,如果你需要更多的信息

每个groovy脚本都有一个名为
binding
的字段、一个
groovy.lang.binding
的实例或它的一个子类。
此绑定基本上是一个映射,具有方法
setVariable
setVariable

当在脚本中赋值时省略
def
关键字时,实际上是在调用方法
setVariable
,当执行类似
this.x
的操作时,则是在调用
getVariable
方法。
这实际上是因为class
groovy.lang.Script
重写了方法
getProperty
setProperty
,以首先调用这些方法。这就是它们行为像字段的原因。
您可能还注意到,没有与这些变量关联的类型。。。这是因为我们只处理绑定内部的
映射。
标准groovy Scrip是通过将
args
设置为参数数组的绑定实例创建的。
其他的,比如
groovy.servlet.ServletBinding
定义更多的变量和行为,比如阻止某些变量的赋值,或者添加延迟初始化功能

那么错误背后的真正原因是。。。如果未使用
def
关键字,
fruits
不是实变量。不过,我相信这种行为在某种程度上类似于场

对此我很抱歉。
我对自己的过分简化并不满意:首先是对groovy脚本的总体回顾:

// file: SomeScript.groovy
x = 1
def x = 2
println x
println this.x
其大致汇编如下:

class SomeScript extends groovy.lang.Script {
  def x
  def run() {
    x = 1
    def x = 2
    println x // 2
    println this.x // 1
  }
}
在groovy脚本中(粗略地说,是一个没有类声明的文件),为未定义的变量赋值被解释为字段赋值

您的示例尝试使用名为
fruit
的参数定义闭包
如果使用
def
关键字定义了
fruit
,则会收到一条错误消息,因为该名称已被视为局部变量,并且不能复制局部变量名称。
当您不使用
def
关键字时,实际上是在将值分配给为脚本生成的类的字段,因此名称
fruit
可以重新定义为局部变量

关于作用域,它很像java…
在该示例中,您可以看到
x
首先定义为一个字段,然后定义为
run()
方法的局部变量。这没有什么问题,您可以访问变量和字段。
但一旦定义了局部变量,就无法创建重复项

编辑--
必须在任何时候之前加上这个