什么是Scala中替代运行时保留注解的方法?

13
我刚刚意识到,我无法在scala中使用在运行时保留和分析的注释。我还查看了这个问题,但我没有完全弄清楚替代方案是什么。
  • DI - 一个回答提到,在scala中没有必要使用DI框架。虽然在基本水平上可能是这样(虽然我不太喜欢那个例子;处理DI的惯用方式是什么?),Java DI框架(如Spring)非常先进,并通过注释处理许多事情,例如定期作业、缓存、管理持久性等,有时还会使用自定义注释。

  • ORM - 我承认我没有尝试过任何原生的scala ORM,但从我在squeryl中看到的内容来看,它也使用了一些注释,这意味着注释是不可避免的吗?

  • 任何序列化工具 - 如何惯用地自定义JSON/XML等序列化输出?

  • Web服务框架 - 如何在代码中定义RESTful或SOAP服务的映射、标头等?

Scala用户需要有一个混合的scala/java(用于注释)项目,才能使用这些来自Java的设施吗?

本地Scala元数据的替代方案比注释更好吗?我还没有完全进入Scala思维模式,因此大多数示例看起来对我来说比使用注释要丑陋,所以请尽量说服我 :)

1个回答

9
实际上,Scala确实有运行时保留的注释。不同之处在于它们不是作为Java注释存储的,而是编码在二进制ScalaSignature注释的内容中(这本身就是一个运行时保留的Java注释)。
因此,Scala注释可以在运行时检索,但是必须使用Scala反射,而不是使用Java反射:
class Awesome extends StaticAnnotation

@Awesome
class AwesomeClass

import scala.reflect.runtime.universe._

val clazz = classOf[AwesomeClass]
val mirror = runtimeMirror(clazz.getClassLoader)
val symbol = mirror.classSymbol(clazz)
println(symbol.annotations) // prints 'List(Awesome)'

不幸的是,Scala反射仍被标记为实验性质,并且实际上在这一点上并不稳定(SI-6240或SI-6826是相当严重的问题示例)。尽管如此,从长远来看,它似乎是Java反射和注释最直接的替代品。

目前,人们必须使用Java注释,我认为这仍然是一个不错的解决方案。

关于DI/ORM/WS/序列化的框架和库 - Scala在这个领域似乎还不够成熟,至少不像Java那样。有很多正在解决这些问题的项目,其中一些已经非常好了,其他一些仍在开发中。以下是我能想到的几个:Squeryl,Slick,Spray,Pickling。

此外,Scala具有一些高级功能,通常使注释变得不必要。类型类(使用隐式参数实现)可能是这方面的一个很好的例子。

https://dev59.com/nHE95IYBdhLWcg3wi-ee 说 StaticAnnotation 在运行时不会被保留。这是否意味着“Java运行时”? - Bozho
@Bozho 我也这么认为。这是三年前 Scala 反射还不存在的时候提出的问题。 - ghik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接