【问题标题】:Class vs Type annotations with Shapeless使用 Shapeless 的类与类型注释
【发布时间】:2019-07-14 23:32:22
【问题描述】:

根据scaladocumentation,有四种注解:

  1. 类注解:@ClassAnnotation case class Foo(...)
  2. 变量/值注释:@ValAnnotation val field: String
  3. 类型注释:field: String @TypeAnnotation
  4. 表达式注释

通过使用shapeless.Annotationshapeless.Annotations,很容易从案例类中获取类和变量注解(1&2)。如何获取其字段的类型注解(三)?

例子:

@ClassAnnotation
case class Foo(
  @ValAnnotation field: String @TypeAnnotation
)

【问题讨论】:

    标签: scala shapeless scala-macros


    【解决方案1】:

    你可以写一个宏

    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]
    

    【讨论】:

    • 所以不支持 shapeless 中的类型注解?
    • @pgrandjean 我猜没有。为什么应该有?并非所有可能的宏都存在于 Shapeless 中。无形处理 ADT(代数数据类型),即密封特征 + 案例对象/案例类。如果您在Foo 处删除修饰符“case”,则将不支持偶数值注释。
    • 我的意思是 Shapeless 是关于类型级编程、泛型编程、依赖类型等。注释来自元编程。
    • Annotations[A, T] 对于从案例类中提取值注释非常有用。我想知道是否也有任何类型注释。虽然它比泛型编程更元编程,但 Annotations[A, T] 包含在 shapeless 中。感谢您的代码!我将创建一个 TypeAnnotations[A, T]。
    • @pgrandjean 是的,我见过。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 2016-09-17
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多