【问题标题】:What's the scala alternative to runtime-preserved annotations运行时保留注释的 scala 替代方案是什么
【发布时间】:2013-08-27 18:39:47
【问题描述】:

我刚刚意识到我不能在 scala 中使用注释,这些注释在运行时会被保留和分析。我还检查了this question,但我不太明白有哪些替代方案。

  • DI - 一个答案提到 Scala 中不需要 DI 框架。虽然在基本层面上可能是这种情况(虽然我不太喜欢that example;处理 DI 的惯用方式是什么?),像 spring 这样的 Java DI 框架非常先进,可以处理许多事情,比如计划作业、缓存、托管持久性等,全部通过注释,有时 - 自定义的。

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

  • 任何序列化工具 - 如何习惯性地将序列化输出自定义为 JSON/XML/...?

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

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

元数据的原生 scala 替代品是否比注释更好?我还没有完全进入 scala 思维模式,因此与使用注释相比,大多数示例对我来说都很难看,所以请尝试更有说服力:)

【问题讨论】:

    标签: scala


    【解决方案1】:

    实际上,Scala 确实有运行时保留的注解。不同之处在于它们不存储为 Java 注释,而是编码在二进制 ScalaSignature 注释的内容中(它本身就是运行时保留的 Java 注释)。

    因此,Scala 注释可以在运行时检索,但不能使用 Java 反射,而必须使用 Scala 反射:

    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-6240SI-6826 是非常严重的问题的例子)。尽管如此,从长远来看,它似乎是 Java 反射和注解最直接的替代品。

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

    关于 DI/ORM/WS/序列化的框架和库 - Scala 在这个领域似乎仍然不成熟,至少不像 Java 那样成熟。有很多针对这些问题的正在进行的项目,其中一些已经非常好,另一些仍在开发中。我想到的几个例子:SquerylSlickSprayPickling

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

    【讨论】:

    • stackoverflow.com/questions/2265773/… 表示在运行时不会保留 StaticAnnotation。这是否意味着“java 运行时”?
    • @Bozho 我想是的。这是三年前 Scala 反射还不存在的问题。
    猜你喜欢
    • 1970-01-01
    • 2014-11-05
    • 2015-07-15
    • 1970-01-01
    • 2021-11-13
    • 2018-12-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-13
    相关资源
    最近更新 更多