Groovy def Keyword – Groovy def 关键字

最后修改: 2019年 4月 21日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick tutorial, we’ll explore the concept of the def keyword in Groovy. It provides an optional typing feature to this dynamic JVM language.

在这个快速教程中,我们将探讨Groovy中的def关键字的概念。它为这种动态JVM语言提供了一种可选的类型化功能。

2. Meaning of the def Keyword

2.def关键词的含义

The def keyword is used to define an untyped variable or a function in Groovy, as it is an optionally-typed language.

def关键字用于定义Groovy中的非类型变量或函数,因为它是一种可选择类型的语言。

When we’re unsure of the type of a variable or field, we can leverage def to let Groovy decide types at runtime based on the assigned values:

当我们不确定一个变量或字段的类型时,我们可以利用def来让Groovy在运行时根据分配的值决定类型。

def firstName = "Samwell"  
def listOfCountries = ['USA', 'UK', 'FRANCE', 'INDIA']

Here, firstName will be a String, and listOfCountries will be an ArrayList.

这里,firstName将是一个String,而listOfCountries将是一个ArrayList

We can also use the def keyword to define the return type of a method:

我们还可以使用def关键字来定义一个方法的返回类型。

def multiply(x, y) {
    return x*y
}

Here, multiply can return any type of object, depending on the parameters we pass to it.

这里,multiply可以返回任何类型的对象,取决于我们传递给它的参数。

3. def Variables

3、def变量

Let’s understand how def works for variables.

让我们了解一下def对变量的作用。

When we use def to declare a variable, Groovy declares it as a NullObject and assign a null value to it:

当我们使用def声明一个变量时,Groovy将其声明为NullObject 并为其分配一个null值。

def list
assert list.getClass() == org.codehaus.groovy.runtime.NullObject
assert list.is(null)

The moment we assign a value to the list, Groovy defines its type based on the assigned value:

当我们给list赋值的时候,Groovy就根据赋值定义了它的类型。

list = [1,2,4]
assert list instanceof ArrayList

Let’s say that we want to have our variable type dynamic and change with an assignment:

比方说,我们想让我们的变量类型是动态的,并随着赋值而改变。

int rate = 20
rate = [12] // GroovyCastException
rate = "nill" // GroovyCastException

We cannot assign List or String to an int typed variable, as this will throw a runtime exception.

我们不能将ListString分配给int类型的变量,因为这将抛出一个运行时异常

So, to overcome this problem and invoke the dynamic nature of Groovy, we’ll use the def keyword:

因此,为了克服这个问题并调用Groovy的动态特性,我们将使用def关键字。

def rate
assert rate == null
assert rate.getClass() == org.codehaus.groovy.runtime.NullObject

rate = 12
assert rate instanceof Integer
        
rate = "Not Available"
assert rate instanceof String
        
rate = [1, 4]
assert rate instanceof List

4. def Methods

4.def方法

The def keyword is further used to define the dynamic return type of a method. This is handy when we can have different types of return values for a method:

def关键字进一步用于定义一个方法的动态返回类型。当我们可以为一个方法提供不同类型的返回值时,这就很方便了。

def divide(int x, int y) {
    if (y == 0) {
        return "Should not divide by 0"
    } else {
        return x/y
    }
}

assert divide(12, 3) instanceof BigDecimal
assert divide(1, 0) instanceof String

We can also use def to define a method with no explicit returns:

我们也可以使用def来定义一个没有明确返回的方法。

def greetMsg() {
    println "Hello! I am Groovy"
}

5. def vs. Type

5.def与类型

Let’s discuss some of the best practices surrounding the use of def.

让我们讨论一下围绕使用def的一些最佳做法。

Although we may use both def and type together while declaring a variable:

尽管我们在声明一个变量时可以同时使用def和type。

def int count
assert count instanceof Integer

The def keyword will be redundant there, so we should use either def or a type.

def关键词在这里将是多余的,所以我们应该使用def或一个类型。

Additionally, we should avoid using def for untyped parameters in a method.

此外,我们应该避免对方法中的未定型参数使用def

Therefore, instead of:

因此,而不是。

void multiply(def x, def y)

We should prefer:

我们应该更喜欢。

void multiply(x, y)

Furthermore, we should avoid using def when defining constructors.

此外,在定义构造函数时,我们应该避免使用def

6. Groovy def vs. Java Object

6.Groovy def与Java Object的比较

As we’ve seen most of the features of the def keyword and its uses through examples, we might wonder if it’s similar to declaring something using the Object class in Java. Yes, def can be considered similar to Object:

由于我们已经通过实例看到了def关键字的大部分特性及其用途,我们可能会想,它是否与使用Java中的Object类来声明某些东西类似。是的,def可以被认为与Object类似。

def fullName = "Norman Lewis"

Similarly, we can use Object in Java:

同样地,我们可以在Java中使用Object

Object fullName = "Norman Lewis";

7. def vs. @TypeChecked

7.def@TypeChecked的对比

As many of us would be from the world of strictly-typed languages, we may wonder how to force compile-time type checking in Groovy. We can easily achieve this using the @TypeChecked annotation.

由于我们中的许多人来自严格类型化语言的世界,我们可能想知道如何在Groovy中强制进行编译时类型检查。我们可以使用@TypeChecked注解来轻松实现。

For example, we can use @TypeChecked over a class to enable type checking for all of its methods and properties:

例如,我们可以在一个类上使用@TypeChecked来启用对其所有方法和属性的类型检查。

@TypeChecked
class DefUnitTest extends GroovyTestCase {

    def multiply(x, y) {
        return x * y
    }
    
    int divide(int x, int y) {
        return x / y
    }
}

Here, the DefUnitTest class will be type checked, and compilation will fail due to the multiply method being untyped. The Groovy compiler will display an error:

在这里,DefUnitTest类将被进行类型检查,由于multiply方法没有类型,编译将失败。Groovy编译器将显示一个错误。

[Static type checking] - Cannot find matching method java.lang.Object#multiply(java.lang.Object).
Please check if the declared type is correct and if the method exists.

So, to ignore a method, we can use TypeCheckingMode.SKIP:

因此,要忽略一个方法,我们可以使用TypeCheckingMode.SKIP

@TypeChecked(TypeCheckingMode.SKIP)
def multiply(x, y)

8. Conclusion

8.结语

In this quick tutorial, we’ve seen how to use the def keyword to invoke the dynamic feature of the Groovy language and have it determine the types of variables and methods at runtime.

在这个快速教程中,我们看到了如何使用def关键字来调用Groovy语言的动态特性,让它在运行时确定变量和方法的类型。

This keyword can be handy in writing dynamic and robust code.

这个关键词在编写动态和健壮的代码时可以很方便。

As usual, the code implementations of this tutorial are available on the GitHub project.

像往常一样,本教程的代码实现可以在GitHub项目中获得。