如何创建注释并在 scala 中获取它们

发布于 2024-10-20 05:04:20 字数 771 浏览 1 评论 0原文

我想定义一些注释并在 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 中正确创建注释?以及如何使用和获取它们?

I want to define some annotations and use them in Scala.

I looked into the source of Scala, found in scala.annotation package, there are some annotations like tailrec, switch, elidable, and so on. So I defined some annotations as them do:

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.

How can I create annotations in Scala correctly? And how to use and get them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

你丑哭了我 2024-10-27 05:04:20

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

以下是一些示例:
在 Scala 2.10 中反映注释

FWIW, you can now define scala annotation in scala 2.10 and use reflection to read them back.

Here are some examples:
Reflecting Annotations in Scala 2.10

时光礼记 2024-10-27 05:04:20

会不会和留存有关系?我敢打赌@tailrec 不包含在生成的字节码中。

如果我尝试扩展 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
      ^

Could it have something to do with retention? I bet @tailrec is not included in the bytecode getting generated.

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:

./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
      ^
风铃鹿 2024-10-27 05:04:20

我认为现在只能在Java中定义注释。

http://www.scala-lang.org/node/106

I think you can only define annotations in Java now.

http://www.scala-lang.org/node/106

国产ˉ祖宗 2024-10-27 05:04:20

您可以在 Programming Scala

所以你可以在scala中定义或使用注解。然而,至少有一个限制:

运行时保留不太可能。理论上,您应该子类化 ClassFileAnnotation 来实现此目的,但如果您这样做,目前 scalac 会报告以下警告:

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

这也意味着您的代码本身就很好(至少与 Scala 中当前可能的一样好),但注释仅在编译时存在于类上。因此,您可以在编译器插件中使用它,但您将无法在运行时访问它。

You can find a nice description of how annotations are to be used in Scala in Programming Scala.

So you can define or use annotations in scala. However there is at least one limitation:

Runtime retention is not quite possible. In theory you should subclass ClassFileAnnotation to achieve this, but currently scalac reports the following warning if you do it:

"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."

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.

征﹌骨岁月お 2024-10-27 05:04:20

在 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
}

With scala 2.11.6, this works to extract values of a annotation:

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文