Groovy:“;def";关键字与具体类型

Groovy:“;def";关键字与具体类型,groovy,Groovy,如果我们知道一个变量的数据类型,并且它在运行时不会改变,那么我们是否应该定义变量的数据类型或方法的返回类型?使用def和实际数据类型的优缺点是什么 一个例子是,如果abc计划成为List List abc=“xyz”//IntelliJ IDEA为不正确的赋值提供语法突出显示 def abc=“xyz”//IntelliJ IDEA不会突出显示语法 由于方便(特别是来自Java的情况下),很容易陷入到处使用def的陷阱 但是正如您所看到的,如果您知道某个内容的类型,最好是键入它,尤其是在公共方法

如果我们知道一个变量的数据类型,并且它在运行时不会改变,那么我们是否应该定义变量的数据类型或方法的返回类型?使用def和实际数据类型的优缺点是什么

一个例子是,如果abc计划成为
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中引入动态类型。正如您在上面的示例中所看到的,这仍然是旧的Java
Object
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();
      }