Class 与 Shapeless 类型注释对比
Class vs Type annotations with Shapeless
根据 scala documentation,有四种注解:
- Class注解:
@ClassAnnotation case class Foo(...)
- Variable/Value注解:
@ValAnnotation val field: String
- 类型注释:
field: String @TypeAnnotation
- 表达式注释
通过使用shapeless.Annotation
和shapeless.Annotations
,很容易从一个案例class中得到class和变量注释(1&2)。如何获取其字段的类型注解(三)?
示例:
@ClassAnnotation
case class Foo(
@ValAnnotation field: String @TypeAnnotation
)
你可以写一个宏
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
def getAnnotation[A]: Any = macro impl[A]
def impl[A: c.WeakTypeTag](c: blackbox.Context): c.Tree = {
import c.universe._
println(weakTypeOf[A].typeSymbol.annotations) // List(ClassAnnotation)
println(weakTypeOf[A]
.member(termNames.CONSTRUCTOR)
.asMethod
.paramLists
.map(_.map(_.annotations))
) // List(List(List(ValAnnotation)))
println(weakTypeOf[A]
.member(termNames.CONSTRUCTOR)
.asMethod
.paramLists
.map(_.map(_.typeSignature match {
case AnnotatedType(annots, _) => annots
case _ => List()
})) // List(List(List(TypeAnnotation)))
)
q""
}
import scala.annotation.StaticAnnotation
case class ClassAnnotation() extends StaticAnnotation
case class ValAnnotation() extends StaticAnnotation
case class TypeAnnotation() extends StaticAnnotation
@ClassAnnotation
case class Foo(
@ValAnnotation field: String @TypeAnnotation
)
getAnnotation[Foo]
根据 scala documentation,有四种注解:
- Class注解:
@ClassAnnotation case class Foo(...)
- Variable/Value注解:
@ValAnnotation val field: String
- 类型注释:
field: String @TypeAnnotation
- 表达式注释
通过使用shapeless.Annotation
和shapeless.Annotations
,很容易从一个案例class中得到class和变量注释(1&2)。如何获取其字段的类型注解(三)?
示例:
@ClassAnnotation
case class Foo(
@ValAnnotation field: String @TypeAnnotation
)
你可以写一个宏
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
def getAnnotation[A]: Any = macro impl[A]
def impl[A: c.WeakTypeTag](c: blackbox.Context): c.Tree = {
import c.universe._
println(weakTypeOf[A].typeSymbol.annotations) // List(ClassAnnotation)
println(weakTypeOf[A]
.member(termNames.CONSTRUCTOR)
.asMethod
.paramLists
.map(_.map(_.annotations))
) // List(List(List(ValAnnotation)))
println(weakTypeOf[A]
.member(termNames.CONSTRUCTOR)
.asMethod
.paramLists
.map(_.map(_.typeSignature match {
case AnnotatedType(annots, _) => annots
case _ => List()
})) // List(List(List(TypeAnnotation)))
)
q""
}
import scala.annotation.StaticAnnotation
case class ClassAnnotation() extends StaticAnnotation
case class ValAnnotation() extends StaticAnnotation
case class TypeAnnotation() extends StaticAnnotation
@ClassAnnotation
case class Foo(
@ValAnnotation field: String @TypeAnnotation
)
getAnnotation[Foo]