在宏中查找实际类型
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
我正在尝试编写一个提取类型信息的宏。这是一个最小化版本。
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