如何创建注释并在 Scala 中获取它们
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5177010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create annotations and get them in scala
提问by Freewind
I want to define some annotations and use them in Scala.
我想定义一些注释并在 Scala 中使用它们。
I looked into the source of Scala, found in scala.annotationpackage, there are some annotations like tailrec, switch, elidable, and so on. So I defined some annotations as them do:
我查看了 Scala 的源代码,发现在scala.annotation包中,有一些注释,例如tailrec、switch、elidable等。所以我像他们一样定义了一些注释:
class A extends StaticAnnotation
@A
class X {
@A
def aa() {}
}
Then I write a test:
然后我写了一个测试:
object Main {
def main(args: Array[String]) {
val x = new X
println(x.getClass.getAnnotations.length)
x.getClass.getAnnotations map { println }
}
}
It prints some strange messages:
它打印了一些奇怪的消息:
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!)
Seems I can't get the annotation aaa.A.
似乎我无法获得注释aaa.A。
How can I create annotations in Scala correctly? And how to use and get them?
如何在 Scala 中正确创建注释?以及如何使用和获取它们?
采纳答案by Wilfred Springer
Could it have something to do with retention? I bet @tailrec is not included in the bytecode getting generated.
它可能与保留有关吗?我敢打赌@tailrec 不包含在生成的字节码中。
If I try to extend ClassfileAnnotation (in order to have runtime retention), Scala tells me that it can't be done, and it has to be done in Java:
如果我尝试扩展 ClassfileAnnotation(为了有运行时保留),Scala 告诉我它不能完成,它必须在 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
^
回答by Veebs
FWIW, you can now define scala annotation in scala 2.10 and use reflection to read them back.
FWIW,您现在可以在 Scala 2.10 中定义 Scala 注释并使用反射来读取它们。
Here are some examples: Reflecting Annotations in Scala 2.10
以下是一些示例: 在 Scala 2.10 中反射注释
回答by Y.H Wong
I think you can only define annotations in Java now.
我认为您现在只能在 Java 中定义注释。
回答by Sandor Murakozi
You can find a nice description of how annotations are to be used in Scala in Programming Scala.
您可以在Programming Scala 中找到有关如何在 Scala 中使用注释的很好的描述。
So you can define or use annotations in scala. However there is at least one limitation:
所以你可以在 Scala 中定义或使用注解。但是,至少有一个限制:
Runtime retention is not quite possible. In theory you should subclass ClassFileAnnotationto achieve this, but currently scalac reports the following warning if you do it:
运行时保留不太可能。理论上,您应该子类化ClassFileAnnotation以实现此目的,但当前 scalac 会在您执行此操作时报告以下警告:
"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."
“实现限制:子类化 Classfile 不会使您的注释在运行时可见。如果这是您想要的,您必须用 Java 编写注释类。”
It also means that your code is fine as it is (at least as fine as it is currently possible in Scala), but the annotation is on the class only during compile time. So you could use it e.g. in compiler plugins, but you will not be able to access it runtime.
这也意味着您的代码没有问题(至少和当前在 Scala 中一样好),但是注解只在编译时出现在类上。所以你可以在编译器插件中使用它,但你将无法在运行时访问它。
回答by Remi Thieblin
With scala 2.11.6, this works to extract values of a annotation:
使用 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
}

