11

前の質問への回答のおかげで、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)

これは、TupleMapが生成される場所です (Travis Brown's answerを参照)。

...

val pairs = weakTypeOf[T].declarations.collect {
  case m: MethodSymbol if m.isAccessor =>
    val name = c.literal(m.name.decoded)
    val value = c.Expr(Select(model, m.name))
    reify(name.splice -> value.splice).tree
}

...

@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
}

しかし、私は部分的に書く必要があるものを見つけることができませんexists。そこに渡すことができるように@transientするにはどうすればよいですか?Annotation

前もって感謝します!

4

1 に答える 1

11

注釈はval、アクセサーではなく、それ自体にあります。にアクセスする最も簡単な方法valは、 on のaccessedメソッドを使用することMethodSymbolです。

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

于 2013-06-21T13:58:34.457 に答える