Types Groovy混合类型

Types Groovy混合类型,types,groovy,groovy-2,Types,Groovy,Groovy 2,我看到,从Groovy 2.0开始,可以向类或方法添加TypeChecked注释,以触发 我必须承认,我对这种事情是如何运作的感到困惑。本文给出了一些简单的例子,如 @TypeChecked Date test() { // compilation error: // cannot assign value of Date // to variable of type int int object = new Date() String[] lette

我看到,从Groovy 2.0开始,可以向类或方法添加
TypeChecked
注释,以触发

我必须承认,我对这种事情是如何运作的感到困惑。本文给出了一些简单的例子,如

@TypeChecked
Date test() {
    // compilation error:
    // cannot assign value of Date 
    // to variable of type int
    int object = new Date()

    String[] letters = ['a', 'b', 'c']
    // compilation error:
    // cannot assign value of type String 
    // to variable of type Date
    Date aDateVariable = letters[0]

    // compilation error:
    // cannot return value of type String 
    // on method returning type Date
    return "today"
}
在这种情况下,一些检查显然会失败。但在一般情况下,例如,在类型检查方法
B
中使用未进行类型检查的方法
A
的返回值。在这种情况下,我看不出编译器如何判断方法
B
类型是否一致,因为它没有足够的关于方法
A
返回值的信息

一般来说,如何在不丢失类型安全性的情况下对代码子集启用类型检查

编辑

我试着举个例子。如果我有一节旧课呢

class Old {
  public getFoo() {
    return 1
  }
}
并尝试从类型检查代码中使用它,如

@TypeChecked
class New {
  int doubleFoo() {
    return 2 * (new Old().foo)
  }
}

编译器只是不知道该做什么,我猜它将无法编译(我没有在这里安装Groovy2来检查)。但如果是这种情况,那么使用Groovy2之前编写的任何代码就成了一个问题。因此,我想象会有更复杂的事情发生,但我不确定会发生什么。

不存在这样的问题。如果从未检查的类调用方法,则使用的是声明的返回类型,其行为与使用Groovy中的Java方法完全相同

以以下为例:

class A {
   int foo() { 1 }
}

@TypeChecked
class B {
   void bar() {
       int x = new A().foo() // uses the type from A.foo, correct
   }
}
现在,想象一下:

class A {
   Date foo() { new Date() }
}

@TypeChecked
class B {
   void bar() {
       int x = new A().foo() // uses the type from A.foo, foo returns a Date, the compiler throws an error
   }
}

请注意,通常,如果代码严重依赖类型检查器显然无法检查的动态代码,则在单个类中使用混合类型检查。例如,如果您依赖于生成器,则会出现这种情况。如果是这样,那么您只需声明一个方法,该方法将使用构建器作为notchecked,其余代码将被选中。只要unchecked方法返回兼容的类型,就可以保证类型安全。

不存在这样的问题。如果从未检查的类调用方法,则使用的是声明的返回类型,其行为与使用Groovy中的Java方法完全相同

以以下为例:

class A {
   int foo() { 1 }
}

@TypeChecked
class B {
   void bar() {
       int x = new A().foo() // uses the type from A.foo, correct
   }
}
现在,想象一下:

class A {
   Date foo() { new Date() }
}

@TypeChecked
class B {
   void bar() {
       int x = new A().foo() // uses the type from A.foo, foo returns a Date, the compiler throws an error
   }
}

请注意,通常,如果代码严重依赖类型检查器显然无法检查的动态代码,则在单个类中使用混合类型检查。例如,如果您依赖于生成器,则会出现这种情况。如果是这样,那么您只需声明一个方法,该方法将使用构建器作为notchecked,其余代码将被选中。只要unchecked方法返回兼容的类型,类型安全就得到了保证。

事实是,一个典型的groovy类如果不是被设计为进行类型检查的,它将具有类似
def foo(){1}
的特性。好的,这应该相当于返回
对象
。例如,当您尝试将此结果输入到一个typechecked方法中,该方法需要一个
int
(或
Integer
,装箱后),类型检查器会抱怨。我对Groovy的经验是否不具有代表性,但是我发现很多代码没有显式声明返回类型,只是使用
def
。我甚至认为这是最好的做法,因为在Groovy 1中声明一个返回类型在任何情况下都不会进行类型检查,而只是在运行时进行强制转换,导致代码不再安全,可能由于强制转换而隐藏了一个bug,而且速度较慢;groovy是一种快速动态语言,所以您需要检查您的情况:是否需要最大性能?我使用groovy在一个web应用程序上工作了两年,我们的问题主要来自JSF1.2内存使用率高和JPA上的映射不好。如果您需要最高性能,请选择CompileStatic。如果需要类型检查,我认为您应该键入方法的签名,否则您可以选择
def
。在您的例子中,我认为编译器没有推断方法的返回类型。也许是填一个JIRA?我并不是说问题在于速度慢,也许我表达得不好。但事实是,在Groovy 1中为返回值添加类型不会带来性能上的好处(如果相反的话),也不会添加类型安全性(它在运行时强制转换),并且可能会隐藏bug。因此,我通常看到的代码不包含返回值的类型提示。这只是一个旁白。实际的问题是:当许多方法返回未知类型的值时,编译器如何进行类型检查?这不是咆哮,我真的想弄明白。我认为这在groovy中不起作用。编译器不会抱怨,也不会推断返回值。这是动态语言的一部分;-)。使用
@CompileStatic
时,如果方法包含
def
,编译器也不会推断返回类型,最好使用显式返回类型。使用groovy时,您的代码应该包含测试。我工作过的一个系统没有任何测试,所以我们总是在方法中使用类型。事实上,一个典型的groovy类(它不是设计用来进行类型检查的)将有类似于
def foo(){1}
的内容。好的,这应该相当于返回
对象
。例如,当您尝试将此结果输入到一个typechecked方法中,该方法需要一个
int
(或
Integer
,装箱后),类型检查器会抱怨。我对Groovy的经验是否不具有代表性,但是我发现很多代码没有显式声明返回类型,只是使用
def
。我甚至认为这是最好的做法,因为在Groovy 1中声明一个返回类型在任何情况下都不会进行类型检查,而只是在运行时进行强制转换,导致代码不再安全,可能由于强制转换而隐藏了一个bug,而且速度较慢;groovy是一种快速动态语言,