这是以下question关于获取通用toMap
和fromMap
(让我们忽略fromMap以便在下面的代码片段中简洁起见)使用Scala的功能的后续行动宏。根据说明,我创建了两个项目:一个包含包含以下内容的宏定义:
package mypackage
import scala.reflect.macros.Context
import scala.language.experimental.macros
trait Mappable[T] {
def toMap(t: T): Map[String, Any]
}
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 = fields.map { field =>
val name = field.name.toTermName
val decoded = name.decoded
q"$decoded -> t.$name"
}
c.Expr[Mappable[T]] {
q"""
new Mappable[$tpe] {
def toMap(t: $tpe): Map[String, Any] = Map(..$toMapParams)
}
"""
}
}
}
子项目具有以下文件,该文件尝试使用父项目的定义:
package mypackage2
import mypackage.Mappable
object MappableTest {
case class Foo(name: String, id: Int) extends Mappable[Foo]
def main(args: Array[String]) {
val f = Foo("asdf", 3)
println(f.toMap(f))
}
}
然而,这会导致以下编译错误,表明子项目知道Mappable,但不是它的两个成员(旁注:我不确定f.toMap(f)
是否是预期的用法api - 有更好的方法吗?):
class Foo needs to be abstract, since: it has 2 unimplemented members. /** As seen from class Foo,
the missing signatures are as follows. * For convenience, these are usable as stub implementations.
*/ def fromMap(map: Map[String,Any]): mypackage2.MappableTest.Foo = ??? def toMap(t:
mypackage2.MappableTest.Foo): Map[String,Any] = ???
有人可以解释为什么会这样,以及我可以做些什么来使这项工作?根据这个link,我认为只要定义和用法在单独的项目中,宏就会起作用。
答案 0 :(得分:0)
编译错误与宏无关。这是关于Foo类没有实现从Mappable继承的抽象mrmbers。