在Scala宏中获取值的好方法是什么?

时间:2014-02-12 18:13:13

标签: scala scala-macros

我有这段代码:

object M {
  implicit class Obj(str: List[_]) {
    def mm(other: String) = macro Test.impl
  }
}

//macro
//in macro i would get a `str` argument with actual value which pass into Obj
//
object Test {
  def impl(c: Context)(other: c.Expr[String]) = { 
    import c.universe._
    ???
    reify{}
  }
} 

目前,我使用

c.prefix.tree {
  case ....
}

但是有更好的选择吗?因为在编译时,我有一个完整的类树,可能有这样的东西:

c.prefix.actualType.someMethodForInitialize.str //get `str` from object

这可能还是有其他人?

示例:

List("a", "b", "c") mm "z"

在宏中我有一棵树:

Apply(Select(Ident(M), newTermName("Obj")),  List(Apply(TypeApply(Select(Select(This(newTypeName("immutable")), scala.collection.immutable.List), newTermName("apply")), List(TypeTree())), List(Literal(Constant("a")), Literal(Constant("b")), Literal(Constant("c"))))))

和实际类型M.Obj 是否可以在没有树遍历的情况下提取List

2 个答案:

答案 0 :(得分:2)

如果您尝试从String中提取other,请使用

val otherStr: String = other.tree match {
  case Literal(Constant(str: String)) => str
}

答案 1 :(得分:2)

虽然这可能不会直接回答你的问题,但很快就会发布2.11你将能够使用quasiquotes为你做所有艰苦的工作:

 val q"${s: String}" = other.tree