问题很简单,定义了一个函数,怎样才能取得参数名?
class User {
def insert(name:String, age: Int) {}
}
在scala中,有没有办法得到这个函数的参数名name和age呢?
因为scala在很多地方受制于java,先让我们看看在java中怎么解决。java的反射,可以得到类名,函数名,参数类型,就是得不到参数的名。曾经在jdk6.0时打算加入,后来因为时间不足放弃,而现在java7.0也没打算加入,可能是考虑到代码的兼容。在java中,不外乎是两种做法:
Paranamer这个库就是按第2种方式做的,见:http://paranamer.codehaus.org/
在scala中,按说也可以这么做。但是我尝试了几次,却都没有成功。scalac的-g参数,后面还有5个可选值,分别是none,source,vars,line,notailcall,我都试了,可是使用paranamer,都什么也没得到,看来scala的编译器跟java的做法还不一样。是不是就没有办法做到了?
最后,在stackoverflow上,有一个高手给我介绍了他写的一个工具,叫scalaj-reflect,可以做到。见:
通过这一段代码:
import scalaj.reflect._
for {
clazz <- Mirror.ofClass[UsersController].toSeq
method <- clazz.allDefs.find(_.name == "insert").toSeq
params <- method.flatParams
} yield params
就可以成功得到insert函数的参数值了。
其项目位于:https://github.com/scalaj/scalaj-reflect
需要手动编译,得到jar。
这么高难的,scala都能解决。
经过后来在实际项目中使用,发现如果一个类的结构比较复杂,比如函数中有内部类或者闭包,可能读取错误。所以如果要使用这个功能,一定要注意测试。