Groovy:"def"关键字vs具体类型

Shi*_*har 11 groovy

如果我们知道数据类型并且它不会在运行时更改,我们是否应该定义变量的数据类型或方法的返回类型?有什么利弊或使用def vs实际数据类型?

一个例子是,如果abc是打算的话 List<String>

List<String> abc = "xyz"; //IntelliJ IDEA gives syntax highlighting for improper assignment
def abc = "xyz"; //IntelliJ IDEA will not give syntax highlighting
Run Code Online (Sandbox Code Playgroud)

tim*_*tes 12

def由于方便(特别是来自Java),很容易陷入使用无处不在的陷阱

但是正如你所看到的,如果你知道某种东西的类型,最好输入它,特别是在公共方法上.好处包括; 自我文档,ide提示,理智......


Szy*_*iak 6

def~ =对象

正如Tim指出的那样,def不是Object数据类型的别名,但它可以作为一个(虽然Object是一个类而def只是一个Groovy关键字) - http://www.groovy-lang.org/semantics.html#_variable_definition唯一的def共同点Object是,在JVM级别上,每个def语句或类型替换都被编译为Object,

考虑非常简单的test.groovy脚本以及以下内容:

def name = "John"

String surname = "Doe"

println "$name $surname"
Run Code Online (Sandbox Code Playgroud)

如果您将其编译为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();
}
Run Code Online (Sandbox Code Playgroud)

IDE语法支持

如果您使用支持Groovy的IDE(例如IntelliJ IDEA),那么您应该能够使用类型推断,IDE将为您提供语法支持.

def关键字的目的

主要目的def是在Groovy中引入动态类型.正如您在上面的示例中所看到的,这仍然是旧的Java Object类型.

好的做法是在有意使用静态类型时使用静态类型.出于文档原因,您的公共API绝对应该使用静态类型.我个人def经常在两种情况下使用:

  • 在具有非常有限的范围和变量名称的局部变量中,提供有关变量本身的所有信息
  • 在Spock单元测试中的测试用例名称,例如 def "should do something"() { }

  • 如果你把所有东西都称为对象,那么groovy将无法正常工作,就好像你把所有东西都称为def ...它不一样 (2认同)