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

查找scala中传递的lambda参数的名称,scala,dsl,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中使用it作为: filter( (age) => age > 10 ) 我

我正在使用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中使用it作为:

filter(  (age) => age > 10 )
我找不到一种方法来知道在DSL中使用了
age
,有什么方法吗

目前,我将字符串作为第一个参数传递,如下所示:

filter( "age",   (age) => age > 10 ) 
并将筛选器更改为将第一个参数作为列名


我想简化DSL。

当前获取lambda实例参数名称的唯一方法是为
过滤器
声明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
。最后,我们实现宏-我们将参数树模式匹配到一个
函数
树中,然后获取第一个参数(
args(0)
),最后将第一个参数模式匹配到一个
ValDef
树中,以便能够提取名称


你可以阅读更多关于宏的内容。

你能添加你的
过滤器
功能的实际实现吗?这将需要一个宏(如果可能的话,我不知道)。如果你把它称为
过滤器(“年龄”(>10))
,这难道不是一个简单的DSL吗?实现很长,但要在问题的上下文中解释一下,筛选器将查询列名称为“age”的整数类型的数据库,并查找所有小于10的值(DSL中定义的应用函数),然后返回最后一个值。基本上,我需要知道我需要应用DSL中传递的条件的列。目前,这就是为什么我首先将列名作为字符串传递argument@ChrisMartin那个下划线会妨碍可读性,所以我将其设计为过滤器({age=>age>10})。我已经搜索了宏,但不确定如何才能做到这一点。谢谢axel22。我试试这个。看起来是完美的解决方案。任何已知的问题,如性能等。我相信宏仍然是实验性的。这是真的-宏仍然是实验性的。性能应该没有问题,因为宏体是在编译时执行的。主要的缺点是,您必须跨两个模块(例如sbt项目)重新构造代码—一个定义宏,另一个使用宏,因为宏不能从定义宏的同一个编译运行中调用。