在宏中查找实际类型

Finding the actual type in macro

我正在尝试编写一个提取类型信息的宏。这是一个最小化版本。

class Extractor[E] {
  def extract(entity: E): Unit = macro ExtractorImpl.extractImpl[E]
}

object ExtractorImpl {
  def extractImpl[E: c.WeakTypeTag](c: Context)(entity: c.Expr[E]): c.Tree = {
    import c.universe._

    val actualType = implicitly[WeakTypeTag[E]].tpe
    c.info(c.enclosingPosition, actualType.toString, true)

    q"{}"
  }
}

这是Extractor的典型实现:

case class Person(name: String)
object PersonExtractor extends Extractor[Person]

如果我像在 PersonExtractor.extract(new Person("test name")) 中一样直接使用此 class,我会得到 Person 作为信息打印。但是,如果我按如下方式间接使用它,它只会打印 E:

class Mapper[E](extractor: Extractor[E]) {
  def extract(e: E) = extractor.extract(e)
}

class PersonMapper extends Mapper[Person](new Extractor[Person])

class Test {
  new PersonMapper().extract(new Person("test name"))
}

如何才能让 Person 类型可用 actualType

使用隐式宏

trait Extractor[E] {
  def extract(entity: E): Unit
}

object Extractor {
  implicit def i[E] : Extractor[E] = macro ExtractorImpl.extractImpl[E]
}

object ExtractorImpl {
  def extractImpl[E: c.WeakTypeTag](c: Context):c.Tree = {
    import c.universe._

    val actualType = c.weakTypeOf[E]
    c.info(c.enclosingPosition, actualType.toString, false)

      q"""
        new Extractor[$actualType]{
          def extract(entity: $actualType): Unit = println("hello world")
        }
      """
  }
}

// 测试

case class Person(name: String)

//object PersonExtractor extends Extractor[Person]

class Mapper[E] {
  def extract(e: E)(implicit extractor: Extractor[E]) = extractor.extract(e)
}

class PersonMapper extends Mapper[Person]

class Test {
  new PersonMapper().extract(new Person("test name")) // show info:Person 
}

编辑: //测试2

class Mapper2[E](extractor: Extractor[E]) {
  def extract(e: E) = extractor.extract(e)
}

object Mapper2 extends Mapper2[Person](Extractor.i[Person])//also  show info:Person