Scala 对函数参数名称的反射 [英] Scala reflection on function parameter names

查看:43
本文介绍了Scala 对函数参数名称的反射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个接受函数的类

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

 def testFunc(name1:String):String = name1
 val res = FunctionParser1Arg(testFunc)

我想从case类里面知道函数的类型签名信息.我想知道参数名称和类型.我已经成功地使用运行时镜像对象找到了类型,但没有找到名称.有什么建议吗?

I would like to know the type signature information on the function from inside the case class. I want to know both the parameter name and type. I have had success in finding the type using the runtime mirror objects, but not the name. Any suggestions?

推荐答案

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

Ok, let's say you got the symbol for the instance func points to:

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

val im = m reflect res.func // Instance Mirror

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

You can get the apply method from its type members:

val apply = newTermName("apply")
val applySymbol = im.symbol.typeSignature member apply

既然我们知道它是一个方法,那就让它成为一个方法符号:

And since we know it's a method, make it a method symbol:

val applyMethod = applySymbol.asMethod

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

It's parameters can be found through paramss, and we know there's only one parameter on one parameter list, so we can get the first parameter of the first parameter list:

val param = applyMethod.paramss(0)(0)

那么你要的是:

val name = param.name.decoded // if you want "+" instead of "$plus", for example
val type = param.typeSignature

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

It's possible that you think that's the wrong answer because you got x$1 instead of name1, but what is passed to the constructor is not the named function testFunc, but, instead, an anonymous function representing that method created through a process called eta expansion. You can't find out the parameter name of the method because you can't pass the method.

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

If that's what you need, I suggest you use a macro instead. With a macro, you'll be able to see exactly what is being passed at compile time and get the name from it.

这篇关于Scala 对函数参数名称的反射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆