2011-03-03 68 views
16

我想定义一些注解并在Scala中使用它们。如何创建注解并将它们放入scala中

我看着斯卡拉的来源,scala.annotation包中发现,有喜欢tailrecswitchelidable,等等一些注释。所以我定义了一些注解为他们做:

class A extends StaticAnnotation 

@A 
class X { 
    @A 
    def aa() {} 
} 

然后我写了一个测试:

object Main { 
    def main(args: Array[String]) { 
     val x = new X 
     println(x.getClass.getAnnotations.length) 
     x.getClass.getAnnotations map { println } 
    } 
} 

它打印出一些奇怪的信息:

1 
@scala.reflect.ScalaSignature(bytes=u1" !1* 1!AbCaE 
9"a!Q!! 1gn!!.<b iBPE*,7 
    Ii#)1oY1mC&1'G.Y(cUGCa#=S:LGO/AA!A 1mI!) 

我似乎不能得到的注解aaa.A

如何正确创建Scala中的注释?以及如何使用并获得它们?

回答

6

它可能与保留有关吗?我打赌@tailrec不包含在生成的字节码中。

如果我试图扩展ClassfileAnnotation(以有保留的运行时),斯卡拉告诉我,它无法做到的,并且它在Java来完成:

./test.scala:1: warning: implementation restriction: subclassing Classfile does not 
make your annotation visible at runtime. If that is what 
you want, you must write the annotation class in Java. 
class A extends ClassfileAnnotation 
    ^
2

你可以找到注解如何在斯卡拉使用在Programming Scala一个很好的说明。

因此,您可以在scala中定义或使用注释。但至少有一个限制:

运行时保留不太可能。从理论上讲,你应该继承ClassFileAnnotation以达到这个目的,但是如果你这么做的话,目前scalac会报告下面的警告:

“实现限制:子类化Classfile不会让你的注释在运行时可见,如果这是你想要的,用Java编写注释类。“

这也意味着你的代码没问题(至少在Scala中可以实现),但注释仅在编译期间才在类上。所以你可以使用它在编译器插件中,但是你将无法访问它的运行时。

+0

你能提供书中的章节/页码? – Jus12 2011-10-04 07:32:11

16

FWIW,您现在可以在scala 2.10中定义scala注释并使用反射来回读它们。

下面是一些例子: Reflecting Annotations in Scala 2.10

+2

谢谢,非常有帮助。你能否在你的答案中加入你的例子的精髓? – Beryllium 2013-12-08 16:24:28

+7

链接被破坏... – evandor 2017-04-12 05:41:58

+0

@evandor +1无效 – 2017-07-06 14:05:46

0

使用Scala 2.11.6,这个工程提取注释值:

case class MyAnnotationClass(id: String) extends scala.annotation.StaticAnnotation 

val myAnnotatedClass: ClassSymbol = u.runtimeMirror(Thread.currentThread().getContextClassLoader).staticClass("MyAnnotatedClass") 
val annotation: Option[Annotation] = myAnnotatedClass.annotations.find(_.tree.tpe =:= u.typeOf[MyAnnotationClass]) 
val result = annotation.flatMap { a => 
    a.tree.children.tail.collect({ case Literal(Constant(id: String)) => doSomething(id) }).headOption 
} 
+0

什么是'你'?你能提供一个合适的例子吗? – 2016-08-31 13:49:41

+0

u代表scala.reflect.runtime.universe – 2016-10-18 15:02:39

相关问题