Scala对函数参数名称的反射

J P*_*lar 2 reflection scala

我有一个功能的类

 case class FunctionParser1Arg[T, U](func:(T => U))

 def testFunc(name1:String):String = name1
 val res = FunctionParser1Arg(testFunc)
Run Code Online (Sandbox Code Playgroud)

我想知道case类中的函数类型签名信息.我想知道参数名称和类型.我已成功使用运行时镜像对象查找类型,但不是名称.有什么建议?

Dan*_*ral 15

好的,假设你得到了实例的符号func指向:

import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => m}

val im = m reflect res.func // Instance Mirror
Run Code Online (Sandbox Code Playgroud)

您可以apply从其类型成员获取该方法:

val apply = newTermName("apply")
val applySymbol = im.symbol.typeSignature member apply
Run Code Online (Sandbox Code Playgroud)

因为我们知道它是一种方法,所以将其作为方法符号:

val applyMethod = applySymbol.asMethod
Run Code Online (Sandbox Code Playgroud)

它的参数可以通过paramss,我们知道一个参数列表上只有一个参数,所以我们可以得到第一个参数列表的第一个参数:

val param = applyMethod.paramss(0)(0)
Run Code Online (Sandbox Code Playgroud)

然后你要求的是:

val name = param.name.decoded // if you want "+" instead of "$plus", for example
val type = param.typeSignature
Run Code Online (Sandbox Code Playgroud)

您可能认为这是错误的答案,因为您得到的x$1不是name1,但传递给构造函数的不是命名函数 testFunc,而是代表通过称为eta扩展的过程创建的方法的匿名函数.您无法找到方法的参数名称,因为您无法传递该方法.

如果那就是你需要的,我建议你改用宏.使用宏,您将能够准确地查看在编译时传递的内容并从中获取名称.