Groovy “def”关键字是可选的吗?如果是,为什么要使用它?

Groovy “def”关键字是可选的吗?如果是,为什么要使用它?,groovy,syntax,Groovy,Syntax,我知道在Groovy中可以使用def关键字动态键入变量。但我也注意到,在某些情况下,它可以被忽略,例如在定义方法参数时,例如funcp1,p2而不是funcdef p1,def p2。不鼓励采用后一种形式 我注意到,这可以扩展到所有代码——只要您想定义一个变量并设置它的值,例如var=2,就可以安全地忽略def关键字。只有在创建时未实例化变量(例如def var1)时,才需要该变量,以便将其实例化为NullObject 这是def唯一有用的时间吗?它是否可以安全地保留在所有其他声明中,例如类和方

我知道在Groovy中可以使用def关键字动态键入变量。但我也注意到,在某些情况下,它可以被忽略,例如在定义方法参数时,例如funcp1,p2而不是funcdef p1,def p2。不鼓励采用后一种形式

我注意到,这可以扩展到所有代码——只要您想定义一个变量并设置它的值,例如var=2,就可以安全地忽略def关键字。只有在创建时未实例化变量(例如def var1)时,才需要该变量,以便将其实例化为NullObject

这是def唯一有用的时间吗?它是否可以安全地保留在所有其他声明中,例如类和方法的声明中?

简短回答:您不能。在某些用例中,跳过类型声明或def关键字是有效的,但这不是一般规则。例如,Groovy脚本允许您在不进行特定类型声明的情况下使用变量,例如

x = 10
然而,它之所以能够工作,是因为groovy.lang.Script类实现和方法在您访问缺少的属性时被触发。在这种情况下,这样的变量被提升为全局绑定,而不是局部变量。如果您尝试在没有实现这些方法的任何其他类上执行相同的操作,那么最终将得到groovy.lang.MissingPropertyException

动态编译和静态编译的Groovy都支持跳过方法声明中的类型。但它有用吗?视情况而定。在大多数情况下,为了更好的可读性和文档目的,最好声明类型。我不建议在公共API中执行此操作-API的用户将看到对象类型,而您可能期望某些特定类型。它表明,如果您的意图是接收任何对象,无论其具体类型是什么,这可能会起作用。例如,像dumpobj这样的方法可以这样工作

最后但并非最不重要的是,有一种方法可以在任何上下文中跳过类型声明。您可以使用最后一个关键字

class Foo {
    final id = 1

    void bar(final name) {
        final greet = "Hello, "

        println greet + name + "!"
    }
}
通过这种方式,您可以获得一段代码,该代码既可以使用动态编译进行编译,也可以使用静态编译进行编译。当然,使用final关键字可以防止您重新分配变量,但是对于编译器来说,这些信息足以推断正确的类型

有关更多信息,您可以查看前一段时间在SO上提出的类似问题:

简短回答:您不能。在某些用例中,跳过类型声明或def关键字是有效的,但这不是一般规则。例如,Groovy脚本允许您在不进行特定类型声明的情况下使用变量,例如

x = 10
然而,它之所以能够工作,是因为groovy.lang.Script类实现和方法在您访问缺少的属性时被触发。在这种情况下,这样的变量被提升为全局绑定,而不是局部变量。如果您尝试在没有实现这些方法的任何其他类上执行相同的操作,那么最终将得到groovy.lang.MissingPropertyException

动态编译和静态编译的Groovy都支持跳过方法声明中的类型。但它有用吗?视情况而定。在大多数情况下,为了更好的可读性和文档目的,最好声明类型。我不建议在公共API中执行此操作-API的用户将看到对象类型,而您可能期望某些特定类型。它表明,如果您的意图是接收任何对象,无论其具体类型是什么,这可能会起作用。例如,像dumpobj这样的方法可以这样工作

最后但并非最不重要的是,有一种方法可以在任何上下文中跳过类型声明。您可以使用最后一个关键字

class Foo {
    final id = 1

    void bar(final name) {
        final greet = "Hello, "

        println greet + name + "!"
    }
}
通过这种方式,您可以获得一段代码,该代码既可以使用动态编译进行编译,也可以使用静态编译进行编译。当然,使用final关键字可以防止您重新分配变量,但是对于编译器来说,这些信息足以推断正确的类型


有关更多信息,您可以查看一个类似的问题,该问题不久前在SO上被问及:

在Groovy中,它在全局变量和局部变量中扮演着重要角色

如果变量名在有def和无def的情况下相同

def被认为是本地的,而没有def则被认为是全局的

我在这里已经详细解释了


因此,如果有人在有和没有它的情况下使用它,将会产生不同的效果,并且可以改变事情。

在Groovy中,它在全局变量和局部变量中扮演着重要的角色

如果变量名在有def和无def的情况下相同

def被认为是本地的,而没有def则被认为是全局的

我在这里已经详细解释了

因此,如果有人使用和不使用它将产生不同,可以改变事情