查找在scala中传递的lambda参数的名称

时间:2015-10-11 08:03:26

标签: scala dsl

我正在使用scala构建DSL,它将根据DSL中的条件过滤数据。

过滤器的功能:

def filter(f: (Int) => (Int)) {
// find what is the name (age) of lambda passed
// query db with column name age and apply function f and return value

}

在DSL中使用它:

filter(  (age) => age > 10 )

我无法找到一种方法来了解在使用DSL age时,有没有办法?

暂时,我将字符串作为第一个参数传递如下:

filter( "age",   (age) => age > 10 ) 

并更改过滤器以将第一个参数作为列名。

我想简化DSL。

1 个答案:

答案 0 :(得分:3)

当前获取lambda实例参数名称的唯一方法是为filter声明Scala宏而不是Scala方法。宏将接收lambda的抽象语法树而不是lambda本身,因此它将能够分析lambda参数的名称。

以下是如何执行此操作的极小示例:

import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context

object MyFilter {
  def filter(p: Int => Int): Unit = macro filterImpl
  def filterImpl(c: Context)(p: c.Expr[Int => Int]): c.Expr[Unit] = {
    import c.universe._

    val Function(args, body) = p.tree
    val ValDef(mods, name, tp, rhs) = args(0)
    println(name)

    reify {
      ()
    }
  }
}

上面,我们首先导入相关的包来启用宏。然后,我们定义 def宏 filter及其实现filterImpl。最后,我们实现宏 - 我们将参数树匹配到Function树中,然后取第一个参数(args(0)),最后将第一个参数模式匹配到{{1}树能够提取名称。

您可以阅读有关宏here的更多信息。