我正在使用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。
答案 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的更多信息。