【发布时间】:2017-01-04 14:48:13
【问题描述】:
我正在尝试编写一个宏,它将案例类的给定实例扩展为字符串表示。例如。 case class Foo(a: Int); Foo(1) 将变为 a -> 1。
所以我编写了一个类型类来为我提供来自名为FieldList 的无形LabelledGeneric 的字段名称。我将 LabelledGeneric 和 FieldList 实例传递给我的宏,我可以轻松地使宏生成所有字段的列表。但是,我不确定如何使用代表字段的字符串从宏主体中的对象访问字段。宏代码如下:
import FieldList._
import shapeless.{HList, LabelledGeneric}
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
object Foo {
def foo_impl[T, L <: HList](c: blackbox.Context)
(t: c.Expr[T])
(gen: c.Expr[LabelledGeneric.Aux[T, L]],
fl: c.Expr[FieldList[L]]): c.Expr[String] = {
import c.universe._
reify {
val sb = new StringBuilder
val obj = t.splice
val generic = gen.splice
val fieldList = fl.splice
// T.fieldList returns a List[String] of the class' fields.
obj.fieldList(generic, fieldList).foldLeft(sb) { case (builder, next) =>
builder.append(next)
builder.append(" -> ")
builder.append() // How to get the value of obj.$next?
}.toString()
}
}
def foo[T, L <: HList](t: T)(implicit gen: LabelledGeneric.Aux[T, L], fl: FieldList[L]): String = macro foo_impl[T, L]
}
我不确定该做什么是我折叠的第 3 行带有注释的行。
我确定我正在尝试做的事情对于普通的无形是可能的,但我正在尝试学习宏。我研究了 quasiquotes,看起来他们可以支持这种行为,但看起来我必须在 reify 和 quasiquotes 和 AFAICT 之间进行选择,我只能在 reify 块中访问 Expr 的值(所以 quasiquotes 不起作用?)。
【问题讨论】: