5

マクロにWeakTypeTag何らかのタイプがあり、次のようにコードを生成したいと考えています。

macroCreate[SomeObject] // => SomeObject(1)

マクロの定義は次のようになります。

def macroCreate[A] = macro _macroCreate[A]
def _macroCreate[A](c: Context)(implicit wtt: c.WeakTypeTag[A]) = {
  c.Expr(Apply(Select(???, newTermName("apply")), List(c.literal(1).tree)))
}

Select問題は、指定されたタイプをどのように取得するかです。

タイプを文字列に変換し、分割してから文字列のリストから"."作成するという回避策を使用できますSelectが、それはハックのようです。

Selectタイプタグから直接作成することは可能ですか?

4

1 に答える 1

8

コンパニオン オブジェクトのシンボルを取得してから、ユニバースのIdent(sym: Symbol): Identファクトリ メソッドを使用できます。

def macroCreate[A] = macro _macroCreate[A]

def _macroCreate[A](c: Context)(implicit wtt: c.WeakTypeTag[A]) = {
  import c.universe._

  c.Expr(
    Apply(
      Select(Ident(wtt.tpe.typeSymbol.companionSymbol), newTermName("apply")),
      c.literal(1).tree :: Nil
    )
  )
}

その後:

scala> case class SomeObject(i: Int)
defined class SomeObject

scala> macroCreate[SomeObject]
res0: SomeObject = SomeObject(1)

scala> macroCreate[List[Int]]
res1: List[Int] = List(1)

SomeObjectそれがオブジェクトの型 (つまり、そのコンパニオン クラスの型ではない) であるということを本当に意味する場合は、.companionSymbol上記を削除してください。

于 2013-07-01T10:10:56.377 に答える