假设我有如下方法:
def getInfo(func: () => T) = {
//Code goes here.
}
如何使用Scala 2.11.1的运行时反射来检查传递的匿名函数func
?
我特别感兴趣的是获取func
的AST(抽象语法树),如果可能的话,获取方法首次定义的位置(行号、文件)。到目前为止,我所完成的只是获取有关参数func
类型的信息,而不是函数本身。
我知道在SO上也有类似的问题,但他们主要针对其他Scala版本。
正如Ben在评论中提到的,这可以在编译时使用Scala宏来完成。
一种可能的选择是将原始调用扩展到一个宏,该宏查询必要的信息,然后调用内部getInfoMethod,该方法对这些信息执行一些操作。
getInfo
函数示例:
import scala.language.experimental.macros
//getInfo method which gets expanded to macro
def getInfo(func: => Any):Unit = macro FindFreeVars.findMacro
def getInfoInternal(info: Any) {
//Do something with the collected information
}
宏示例:
//Macro delclaration
def getInfoMacro(c: Context)(func: c.Tree): c.Expr[Unit] = {
import c.universe._
//Extract information, like enclosingPosition or symols from the function tree.
val functionInfo = getFunctionInfo(func)
//Call internal method
c.Expr[List[(String, Any)]](q"getInfoInternal($func, $closedVars)")
}
更多关于符号、树和类型的分析。
一个更完整的宏示例,它通过应用相同的技术找到从函数的另一个作用域绑定的所有变量。