Groovy:“;def";关键字与具体类型
如果我们知道一个变量的数据类型,并且它在运行时不会改变,那么我们是否应该定义变量的数据类型或方法的返回类型?使用def和实际数据类型的优缺点是什么 一个例子是,如果abc计划成为Groovy:“;def";关键字与具体类型,groovy,Groovy,如果我们知道一个变量的数据类型,并且它在运行时不会改变,那么我们是否应该定义变量的数据类型或方法的返回类型?使用def和实际数据类型的优缺点是什么 一个例子是,如果abc计划成为List List abc=“xyz”//IntelliJ IDEA为不正确的赋值提供语法突出显示 def abc=“xyz”//IntelliJ IDEA不会突出显示语法 由于方便(特别是来自Java的情况下),很容易陷入到处使用def的陷阱 但是正如您所看到的,如果您知道某个内容的类型,最好是键入它,尤其是在公共方法
List
List abc=“xyz”//IntelliJ IDEA为不正确的赋值提供语法突出显示
def abc=“xyz”//IntelliJ IDEA不会突出显示语法
由于方便(特别是来自Java的情况下),很容易陷入到处使用def
的陷阱
但是正如您所看到的,如果您知道某个内容的类型,最好是键入它,尤其是在公共方法上。好处包括:;自我文档、ide提示、健全性…def~=Object
正如Tim指出的,def
是而不是Object
数据类型的别名,但它可以是一个(Object
是一个类,而def
只是一个Groovy关键字)-def
与Object
唯一的共同点是,在JVM级别,每个def
语句或类型替换都被编译为Object
考虑包含以下内容的非常简单的test.groovy
脚本:
def name = "John"
String surname = "Doe"
println "$name $surname"
如果将其编译为test.class
,并查看反编译代码,您将看到:
Compiled from "test.groovy"
public class test extends groovy.lang.Script {
public static transient boolean __$stMC;
public test();
LocalVariableTable:
Start Length Slot Name Signature
4 4 0 this Ltest;
public test(groovy.lang.Binding);
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 this Ltest;
0 9 1 context Lgroovy/lang/Binding;
public static void main(java.lang.String...);
LocalVariableTable:
Start Length Slot Name Signature
0 19 0 args [Ljava/lang/String;
public java.lang.Object run();
LineNumberTable:
line 1: 4
line 3: 9
line 5: 14
LocalVariableTable:
Start Length Slot Name Signature
0 63 0 this Ltest;
7 56 2 name Ljava/lang/Object;
12 51 3 surname Ljava/lang/String;
protected groovy.lang.MetaClass $getStaticMetaClass();
}
IDE语法支持
如果您使用支持Groovy的IDE(例如IntelliJ IDEA),那么您应该能够使用类型推断,IDE将为您提供语法支持
def
关键字的用途
def
的主要目的是在Groovy中引入动态类型。正如您在上面的示例中所看到的,这仍然是旧的JavaObject
type
好的做法是,只要您有意使用静态类型,就使用静态类型。出于文档的原因,您的公共API肯定应该使用静态类型。我个人经常在两种情况下使用def
:
- 在范围非常有限的局部变量中,变量名提供了有关变量本身的所有信息
- 在测试用例名称中的Spock单元测试中,例如
def“应该做某事”({}
- @tim_yates是否将
def
编译成与对象不同的东西?我想我知道你的意思def
不是类,而Object
是类-有一些方法可以调用Object
,例如Object.getClass()
,但是在def
上没有任何方法可以调用。还有其他区别吗?
Compiled from "test.groovy"
public class test extends groovy.lang.Script {
public static transient boolean __$stMC;
public test();
LocalVariableTable:
Start Length Slot Name Signature
4 4 0 this Ltest;
public test(groovy.lang.Binding);
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 this Ltest;
0 9 1 context Lgroovy/lang/Binding;
public static void main(java.lang.String...);
LocalVariableTable:
Start Length Slot Name Signature
0 19 0 args [Ljava/lang/String;
public java.lang.Object run();
LineNumberTable:
line 1: 4
line 3: 9
line 5: 14
LocalVariableTable:
Start Length Slot Name Signature
0 63 0 this Ltest;
7 56 2 name Ljava/lang/Object;
12 51 3 surname Ljava/lang/String;
protected groovy.lang.MetaClass $getStaticMetaClass();
}