Как создавать аннотации и получать их в Scala - PullRequest
17 голосов
/ 03 марта 2011

Я хочу определить некоторые аннотации и использовать их в Scala.

Я посмотрел на источник Scala, находящийся в пакете scala.annotation, есть некоторые аннотации, такие как tailrec, switch, elidable и так далее. Поэтому я определил некоторые аннотации, как они делают:

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? А как их использовать и получить?

Ответы [ 5 ]

16 голосов
/ 02 февраля 2013

FWIW, теперь вы можете определить аннотацию scala в scala 2.10 и использовать отражение, чтобы прочитать их обратно.

Вот несколько примеров: Отражение аннотаций в Scala 2.10

6 голосов
/ 03 марта 2011

Может ли это быть связано с удержанием? Бьюсь об заклад, @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
      ^
3 голосов
/ 03 марта 2011

Я думаю, что теперь вы можете определять только аннотации в Java.

* ** 1003 тысяча два *http://www.scala -lang.org / узел / 106
2 голосов
/ 03 марта 2011

Вы можете найти хорошее описание того, как аннотации будут использоваться в Scala в Программирование Scala .

Таким образом, вы можете определять или использовать аннотации в Scala.Однако есть как минимум одно ограничение:

Сохранение во время выполнения не вполне возможно.Теоретически вы должны создать подкласс ClassFileAnnotation для достижения этой цели, но в настоящее время скалак выдает следующее предупреждение, если вы делаете это:

"ограничение реализации: создание подкласса Classfile не делает вашу заметку видимой во время выполнения. Если это то, что выхотите, вы должны написать класс аннотаций в Java. "

Это также означает, что ваш код в порядке, как он есть (по крайней мере, настолько хорош, насколько это возможно в настоящее время в Scala), но аннотация в классетолько во время компиляции.Таким образом, вы можете использовать его, например, в плагинах компилятора, но не сможете получить к нему доступ во время выполнения.

0 голосов
/ 01 июня 2016

В 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...