【发布时间】:2014-05-29 21:38:58
【问题描述】:
我正在尝试理解以下博客文章,其中讨论了如何使用宏创建基于宏的通用方法来将案例类对象与映射相互转换:http://blog.echo.sh/post/65955606729/exploring-scala-macros-map-to-case-class-conversion
尽管我阅读了整篇文章和另一篇关于 scala 宏的文章,但我仍然不完全理解它们是如何工作的。不幸的是,我从博客文章中给出的示例代码中收到了几个编译错误,我不确定为什么会发生错误,也不知道如何解决它们。为了完整性,我正在复制下面的代码,前面是编译错误(我用 cmets 对代码 sn-p 进行了关于编译错误的注释)。有谁知道为什么会出现这些编译器问题以及如何解决它们?
-type mismatch; found : field.NameType required:
c.universe.TermName
-Can't unquote List[Nothing] with .., bottom type values often indicate programmer mistake
代码如下:
import scala.reflect.macros.Context
import scala.language.experimental.macros
trait Mappable[T] {
def toMap(t: T): Map[String, Any]
def fromMap(map: Map[String, Any]): T
}
object Mappable {
implicit def materializeMappable[T]: Mappable[T] = macro materializeMappableImpl[T]
def materializeMappableImpl[T: c.WeakTypeTag](c: Context): c.Expr[Mappable[T]] = {
import c.universe._
val tpe = weakTypeOf[T]
val companion = tpe.typeSymbol.companionSymbol
val fields = tpe.declarations.collectFirst {
case m: MethodSymbol if m.isPrimaryConstructor ⇒ m
}.get.paramss.head
val (toMapParams, fromMapParams) = fields.map { field ⇒
val name = field.name
val decoded = name.decoded
val returnType = tpe.declaration(name).typeSignature
(q"$decoded → t.$name", q"map($decoded).asInstanceOf[$returnType]") // error 1
}.unzip
c.Expr[Mappable[T]] {
q"""
new Mappable[$tpe] {
def toMap(t: $tpe): Map[String, Any] = Map(..$toMapParams)
def fromMap(map: Map[String, Any]): $tpe = $companion(..$fromMapParams) // error 2
}
"""
}
}
}
【问题讨论】: