我定义了一个简单的通用宏:
object MyMacro {
def readWrite[T](readParse: String => T, label: String, format: T => String): Unit = macro readWriteImpl[T]
def readWriteImpl[T: c.WeakTypeTag](c: Context)(readParse: c.Expr[String => T], label: c.Expr[String], format: c.Expr[T => String]): c.Tree = {
import c.universe._
q"""
def read[WIRE](path: Path, reader: Transceiver[WIRE], isMapKey: Boolean = false): T =
reader.readString(path) match {
case null => null.asInstanceOf[T]
case s => Try( $readParse(s) ) match {
case Success(d) => d
case Failure(u) => throw new ReadMalformedError(path, "Failed to parse "+$label+" from input '"+s+"'", List.empty[String], u)
}
}
def write[WIRE](t: T, writer: Transceiver[WIRE], out: Builder[Any, WIRE]): Unit =
t match {
case null => writer.writeNull(out)
case _ => writer.writeString($format(t), out)
}
"""
}
}
在一个单独的编译单元中,我像这样使用它:
object DurationTypeAdapterFactory extends TypeAdapter.=:=[Duration] {
MyMacro.readWrite[Duration]((s: String) => Duration.parse(s), "Duration", (t: Duration) => t.toString)
}
编译时,编译器抱怨它不知道 T:
[error] /Users/me/git/ScalaJack/core/src/main/scala/co.blocke.scalajack/typeadapter/TimePrimitives.scala:13:30: not found: type T
[error] MyMacro.readWrite[Duration]((s: String) => Duration.parse(s), "Duration", (t: Duration) => t.toString)
[error]
它不喜欢我的准引用中的“T”引用,我有点理解。如何表示传递给准引用内的 readWriteImpl 的 T 参数,以便它正确解包?