【发布时间】:2021-01-26 13:17:48
【问题描述】:
我有一个 scala 代码:特征模型及其实现案例类 Category 带有我希望稍后阅读的自定义注释
import scala.annotation.StaticAnnotation
class ExtraFields() extends StaticAnnotation
trait Model {}
case class MyCategory( id: Option[Int],
name: String,
level: Option[Int],
@ExtraFields
parent: Option[MyCategory] = None
) extends Model {
}
我有 trait DBModel 及其实现 MyCategoryModel。我将 MyCategory 作为类型参数传递给 DBModel
trait DBModel[T <: Model] {
lazy val fields = getClassFields[T]
lazy val fields2 = getClassFields2[T]
}
object MyCategoryModel extends DBModel[MyCategory] {
def getFields = fields
def getFields2 = fields2
}
我希望 trait DBModel 读取作为 T 参数传递的案例类的字段,所以我调用了两个函数
def getClassFields[T] = {
symbolOf[T].asClass.primaryConstructor
.typeSignature.paramLists.head.map {v =>
v.name.toString -> v.annotations
}
}
def getClassFields2[T: TypeTag]: Iterable[(String, List[universe.Annotation])] =
typeOf[T].members.collect {
case m: MethodSymbol if m.isCaseAccessor =>
m.name.toString -> m.annotations
}
但它们都不起作用
val res = MyCategoryModel.getFields // runtime exception: free type T is not a class
val res2 = MyCategoryModel.getFields2 // compile error: No TypeTag available for T
如果我直接打电话给他们
getClassFields[MyCategory]
getClassFields2[MyCategory]
对于第一个函数我得到同样的错误,对于第二个我得到结果但是 Universe.annotations 看不到我的 ExtraFields 注释,为每个字段返回空列表
您能否解释一下这个黑魔法以及在我的情况下如何征服它 谢谢
UPD 游乐场https://scastie.scala-lang.org/DTTTyA0CSTSZ0Vj7KFW6Hw
【问题讨论】:
-
可以在编译时找到注解
shapeless.Annotations[ExtraFields, MyCategory].apply()。这会产生None :: None :: None :: Some(ExtraFields@4f5991f6) :: HNil。 -
@DmytroMitin,这对我来说更方便,谢谢
标签: scala generics reflection scala-reflect