在Groovy中显式键入:有时还是从不?

2022-09-02 10:27:44

[稍后:仍然无法确定Groovy是否具有静态类型(似乎没有),或者使用显式类型生成的字节码是否不同(似乎是)。无论如何,关于这个问题]

Groovy和其他动态语言(或者至少是Ruby)之间的主要区别之一是,您可以在需要时静态显式键入变量。

也就是说,什么时候应该在Groovy中使用静态类型?以下是我能想到的一些可能的答案:

  1. 仅当出现性能问题时。静态类型变量在Groovy中更快。(或者他们是?关于这个链接的一些问题)
  2. 在类的公共接口(方法,字段)上,因此您可以自动完成。这是可能的/真实的/完全错误的吗?
  3. 永远不会,它只是混乱的代码并破坏了使用Groovy的目的。
  4. 是,当您的类将被继承或使用时

我不仅对你所做的事情感兴趣,更重要的是你对用Groovy编码的项目所看到的感兴趣。规范是什么?

注意:如果这个问题在某种程度上是错误的,或者错过了某些类别的静态动态,请告诉我,我会解决它。


答案 1

根据我的经验,没有规范。有些人经常使用类型,有些人从不使用它们。就个人而言,我总是尝试在方法签名中使用类型(用于参数和返回值)。例如,我总是写这样的方法

Boolean doLogin(User user) {
// implementation omitted
}

即使我可以这样写

def doLogin(user) {
// implementation omitted
}

我这样做是出于以下原因:

  1. 文档:其他开发人员(和我自己)知道该方法将提供和返回哪些类型,而无需阅读实现
  2. 类型安全:虽然Groovy中没有编译时检查,但如果我使用非User参数调用静态类型版本,它将立即失败,因此问题可能很容易解决。如果我调用动态类型版本,它将在调用方法后的一段时间内失败,并且失败的原因可能不会立即显现出来。doLogin
  3. 代码完成:这在使用良好的IDE(即IntelliJ)时特别有用,因为它甚至可以为动态添加的方法(例如域类的动态查找器)提供完成

出于同样的原因,我在方法的实现中也经常使用类型。事实上,我唯一不使用类型的时候是:

  1. 我真的想支持各种各样的类型。例如,将字符串转换为数字的方法也可以将字符串的集合或数组隐藏为数字。
  2. 懒惰!如果变量的作用域非常短,我已经知道要调用哪些方法,并且我还没有导入类,那么声明类型似乎比它的价值更麻烦。

顺便说一句,我不会太相信你链接到的那篇博客文章,声称打字的Groovy比非打字的Groovy快得多。我以前从未听说过,我也不认为证据很有说服力。


答案 2

我参与了几个Groovy项目,我们坚持这样的惯例:

  • 必须指定公共方法中的所有类型。

    public int getAgeOfUser(String userName){ ... }

  • 所有私有变量都使用 def 关键字声明。

这些约定允许您实现许多目标。

首先,如果您使用联合编译,您的java代码将能够轻松地与您的时髦代码进行交互。其次,这种明确的声明使大型项目中的代码更具可读性和可持续性。当然,自动完成也是一个重要的好处。

另一方面,方法的范围通常很小,不需要显式声明类型。顺便说一句,即使您使用 defs,现代 IDE 也可以自动完成局部变量。


推荐