为什么scala人不喜欢注释?

时间:2011-12-22 20:13:53

标签: scala annotations

.NET中的属性是一个非常受欢迎的功能。并且Java在1.5之后添加了Annotation 注释在任何地方都使用,请参阅Java EE和Spring。 但是很少有scala库使用注释。 lift-json不要使用它。 电梯记录不使用它。 Squeryl不使用它。 subcut不使用它。(它有编译器插件的注释) ... 仅举几例。

他们只在需要一些编译器魔法时使用注释。 @tailrec,@ inline,@ BundProperty,@ Inject(在subcut中)......

Scala具有超灵活的类型系统,特征,隐式和Menifest [X]。那么他们不需要运行时元数据吗?

是否有任何scala项目大量使用注释?

P.S。我认为Dynamic应该是注释而不是特征。

4 个答案:

答案 0 :(得分:28)

一般情况下,我们不使用注释,因为我们并没有真正需要它们。

我见过的几个地方使用了注释:

  • 额外类型系统(例如用于分隔延续的CPS插件或效果跟踪插件。
  • 与旧版Java接口连接。 (scala-mojo-support
  • 执行/启用编译器优化,例如@inline@tailrec

在Scala中,我们并不需要依赖注入框架,因为有几种方法可以依赖注入,而不需要外部工具。您可以将DI配置与核心代码分开,但仍然使用Scala编写。请参阅:https://github.com/jsuereth/scala-in-depth-source/blob/master/chapter11/src/main/scala/scalax/config/Test.scala

所以基本的答案是,注释没有任何问题,我们通常(还)不需要它们。

答案 1 :(得分:13)

对我而言,这通常是编译器强制类型安全的问题。看看Squeryl以及它与Hibernate等Java ORM的区别。 Hibernate将使用@Id注释来表示主键,在Squeryl中,您将创建一个id成员,该成员由KeyedEntity特征指定。需要具有主键的实体(例如,更新和删除)的方法将在编译时大声崩溃(如果尚未定义)。 Squeryl还有其他几个地方,其中类型安全构造取代了集合映射和日期/时间处理等注释。

我认为这是Scala社区中常见的思维方式。注释更多是运行时功能,并没有得到充分考虑。 Scala编译器功能非常强大,可以将更多代码推送到可以验证的构造中,这对于那些愿意接受随之而来的复杂性的人来说是有意义的。

答案 2 :(得分:2)

当你说它们被用于编译魔术时,你已经回答了自己的问题。对于其他用途,它通常是某种运行时魔术,其中两个主要工具是反射和字节码转换。

对于JSON案例,转换的选择如下: 1.解析JValue并构建类T的函数或类。 2.对目标类的反思以确定它们的布局和什么是可选的,然后是一些“动态”代码,它运行在解析后的数据上以创建然后最终转换为适当的类型。

答案 3 :(得分:0)

@tailrec和@inline等所有注释都只是编译时。它们扩展了StaticAnnotation,即AFAIK,它是Scala中唯一的注释支持,并且它们不会在运行时保留。我认为理念是避免运行时注释,因为它们是通过反射检索的,这个世界中编译器由于类型擦除而无法再帮助你超越标准类,但最重要的是,因为它是运行时的目标是决定你在编译时决定做什么。

例如,使用注释来建模JSON输出:在Java中,您可以知道在运行程序时它是否正常工作。在Scala中,您可以使用类型类来模拟每种类型在JSON中的表达方式。如果您错过了一个定义,编译将告诉您。一个很好的例子是spray-json

Dave Whittaker在他的answer中给出了另一个很好的例子。