Groovy def关键字

Groovy def Keyword

1.概述

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

2. def关键字的含义

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

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

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

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

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

1
2
3
def multiply(x, y) {
    return x*y
}

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

3. def变量

让我们了解一下def如何作用于变量。

当我们使用def声明变量时,Groovy将其声明为NullObject并为其分配空值:

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

当我们为列表分配值时,Groovy根据分配的值定义其类型:

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

假设我们要使变量类型具有动态性并通过赋值进行更改:

1
2
3
int rate = 20
rate = [12] // GroovyCastException
rate ="nill" // GroovyCastException

我们无法将List或String分配给int类型的变量,因为这将引发运行时异常。

因此,要克服此问题并调用Groovy的动态特性,我们将使用def关键字:

1
2
3
4
5
6
7
8
9
10
11
12
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关键字进一步用于定义方法的动态返回类型。当我们可以为方法使用不同类型的返回值时,这很方便:

1
2
3
4
5
6
7
8
9
10
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

我们也可以使用def定义没有显式返回的方法:

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

5.定义与类型

让我们讨论一些围绕def使用的最佳实践。

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

1
2
def int count
assert count instanceof Integer

def关键字在那里是多余的,因此我们应该使用def或类型。

此外,我们应避免在方法中对未类型化的参数使用def。

因此,代替:

1
void multiply(def x, def y)

我们应该选择:

1
void multiply(x, y)

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

6. Groovydefvs。 Java对象

正如我们通过示例看到def关键字的大多数功能及其用法一样,我们可能想知道它是否类似于使用Java中的Object类声明某些内容。是的,可以将def与Object相似:

1
def fullName ="Norman Lewis"

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

1
Object fullName ="Norman Lewis";

7. def与@TypeChecked

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

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

1
2
3
4
5
6
7
8
9
10
11
@TypeChecked
class DefUnitTest extends GroovyTestCase {

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

在这里,将对DefUnitTest类进行类型检查,并且由于未键入乘法方法,编译将失败。 Groovy编译器将显示错误:

1
2
[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.

因此,要忽略方法,可以使用TypeCheckingMode.SKIP:

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

8.结论

在本快速教程中,我们已经了解了如何使用def关键字来调用Groovy语言的动态功能,并使其在运行时确定变量和方法的类型。

此关键字在编写动态且健壮的代码时会很方便。

与往常一样,本教程的代码实现可在GitHub项目上找到。