Annotationen
Annotationen werden zu einfachen Werten: Klassenname der Annotation und ihre Argumente nach Namen. Scala-Annotationen funktionieren wie Java-Annotationen, weil der Compiler sie liest, nicht die Laufzeit.
Klassen und Properties
Argumente nach Namen
Eine StaticAnnotation ist für Laufzeit-Reflection unsichtbar, für ein Makro aber nicht. Der Deskriptor behält sie mit dem Wert, den sie bekommen hat.
- customer.getAnnotation("demo.Label")
- Some(Annotation(demo.Label,Map(text -> Customer record)))
- name.getAnnotation("demo.Label")
- Some(Annotation(demo.Label,Map(text -> Full name)))
- name.getAnnotation("demo.Label").map(_.parameters("text"))
- Some(Full name)
scala
final class Label(val text: String) extends StaticAnnotation
@Label("Customer record")
case class Customer(@(Label @field)("Full name") name: String, email: String)
val customer = ReflectMacros.reflect[Customer]
customer.getAnnotation("demo.Label")
customer.getProperty("name").flatMap(_.getAnnotation("demo.Label")).map(_.parameters("text"))
Ziele
Das Feld annotieren
Eine einfache Annotation an einem Klassenparameter bleibt am Konstruktorparameter. @(Label @field) setzt sie auf das Feld, wo der Property-Deskriptor sie findet.
- @Label name: String
- Nur am Konstruktorparameter.
- @(Label @field) name: String
- Am Feld: von getProperty("name") gefunden.
- @Label class Customer
- An der Klasse: von descriptor.getAnnotation gefunden.
Einsatz
Beschriftungen, Validierung, Mapping
Weil Annotationen bis nach Scala.js überleben, liest der Browser dieselben Regeln wie der Server: eine Formularbeschriftung, eine Maximallänge, einen Spaltennamen.
scala
def label(descriptor: ClassDescriptor, property: String): String =
descriptor.getProperty(property)
.flatMap(_.getAnnotation("demo.Label"))
.flatMap(_.parameters.get("text"))
.map(_.toString)
.getOrElse(property)