Scala宏:检查某个注释
由于对的回答,我能够创建一个函数宏,这样它将返回一个Scala宏:检查某个注释,scala,annotations,scala-macros,Scala,Annotations,Scala Macros,由于对的回答,我能够创建一个函数宏,这样它将返回一个Map,该映射将每个字段名映射到其类的值,例如 ... trait Model case class User (name: String, age: Int, posts: List[String]) extends Model { val numPosts: Int = posts.length ... def foo = "bar" ... } 所以这个命令 val myUser = User("Foo", 2
Map
,该映射将每个字段名映射到其类的值,例如
...
trait Model
case class User (name: String, age: Int, posts: List[String]) extends Model {
val numPosts: Int = posts.length
...
def foo = "bar"
...
}
所以这个命令
val myUser = User("Foo", 25, List("Lorem", "Ipsum"))
myUser.asMap
返回
Map("name" -> "Foo", "age" -> 25, "posts" -> List("Lorem", "Ipsum"), "numPosts" -> 2)
这是生成Map
的Tuple
s的地方(参见Travis Brown的):
现在我想忽略带有@transient
注释的字段。如何检查方法是否具有@transient
注释
我正在考虑将上面的代码片段修改为
val pairs = weakTypeOf[T].declarations.collect {
case m: MethodSymbol if m.isAccessor && !m.annotations.exists(???) =>
val name = c.literal(m.name.decoded)
val value = c.Expr(Select(model, m.name))
reify(name.splice -> value.splice).tree
}
但是我找不到我需要在存在部分中编写的内容。如何将@transient
作为注释
传递到那里
提前谢谢 注释将位于val
本身,而不是访问器上。访问val
的最简单方法是通过MethodSymbol
上的accessed
方法:
def isTransient(m: MethodSymbol) = m.accessed.annotations.exists(
_.tpe =:= typeOf[scala.transient]
)
现在,您可以在您的collect
中编写以下内容:
case m: MethodSymbol if m.isAccessor && !isTransient(m) =>
请注意,我在这里给出的isTransient
版本必须在宏中定义,因为它需要从c.universe
导入,但是如果在多个宏中执行此类操作,则可以通过添加universe
参数将其分解 再次感谢!我似乎无法获得注释。在上面的示例类中,我在name
和numPosts
之前添加了@transient
,但它们仍然添加到映射中。奇怪的是,通过的方法中似乎没有任何一个是瞬态的。m.accessed.annotations
和m.annotations
都是空的。这很奇怪,在这两种情况下,它对我都有效。你能把你的确切密码发出来吗?这是密码。请注意,我在这里构建了一些稍有不同的东西——给定包下所有字段和case类的字段类型的映射。问题是没有WeakTypeTag吗?提前谢谢。今天开始自己工作。。。我不知道发生了什么事。谢谢你的回答。@EugeneBurmako,没错。这正是问题所在。我刚刚发现调用println(m+”,“+m.typeSignature+”->“+m.accessed.annotations.foreach(a=>println(a.tpe))
可以使宏工作,而println(m+”->“+m.accessed.annotations.foreach(a=>println(a.tpe))
不会显示任何内容。我是来报案的。真是巧合,我用了确切的方法找出了问题所在。非常感谢。那是一个令人讨厌的问题!:)
case m: MethodSymbol if m.isAccessor && !isTransient(m) =>