在运行时获取Scala变量名

在运行时获取Scala变量名,scala,Scala,是否可以在运行时获取scala变量的名称 例如,是否可以编写一个函数getIntVarName(变量:Int):String,其行为如下 val myInt = 3 assert("myInt" === getIntVarName(myInt)) 我认为不可能获得变量的名称,但您可以尝试使用对象: object Test1 { def main(args: Array[String]) { object MyVar { def value = 1 } p

是否可以在运行时获取scala变量的名称

例如,是否可以编写一个函数
getIntVarName(变量:Int):String
,其行为如下

val myInt = 3
assert("myInt" === getIntVarName(myInt))

我认为不可能获得变量的名称,但您可以尝试使用对象:

object Test1 {
  def main(args: Array[String]) {
    object MyVar {
      def value = 1
    }
    println(MyVar.getClass)
  }
}

这将打印:
类Test1$MyVar$2$
。因此,您可以从中获得“MyVar”。

就这样的元数据而言,Scala还没有Java那么多。请密切关注,但我怀疑这是否能在短期内提供对局部变量的访问。同时,考虑一个字节码检查器库。另一个大警告:局部变量名在编译过程中丢失,因此您需要在“调试”模式下编译以保留它们。

基本上,这是无法做到的

JVM通过方法句柄不提供任何东西(记住,Scala属性被编码为字节码中的方法以支持统一访问原则)。您能得到的最接近的方法是使用反射来查找在特定类上定义的方法列表——我知道这对您的特定需求没有帮助

可以将其实现为Scala功能,但这需要一个编译器插件从AST中获取相关的符号名,并将其作为字符串文本推送到代码中,因此我无法在简短的代码段中演示:)


反射中经常出现的另一个命名问题是方法参数。至少我能帮上忙。我有一个基于
scalap
使用的编译器生成的scala签名的。它还远没有准备好正式使用,但它正在积极开发中。

对于您需要做的事情,在我看来,似乎不需要运行时,因为您已经在编译时定义了myInt变量。如果是这种情况,您只需要通过宏进行一点AST操作

试一试

请注意,宏必须作为单独的子项目进行编译,并且不能是必须应用宏替换的同一项目的一部分。检查此模板,了解如何定义此类宏子项目:

可以使用获取变量名、函数名、类成员名或类型名。它发生在编译时,因此不涉及反射,也不需要运行时依赖项

val myInt = 3
assert("myInt" === nameOf(myInt))
将编译为:

val myInt = 3
assert("myInt" === "myInt")

@KingCrunch-当你想记录一些东西以进行调试,或者将一个对象转换成一个映射或其他一些动态结构以用于ORM框架和类似的东西时,它非常方便?假设
def foo(i:Int)=ValueOf(“res”+i)
,ValueOf是假设的函数。现在(使用Scala 2.11),是否可以使用Scala反射API获取变量名或实例名?我们怎样才能做到这一点呢?@metch看看我的答案。这是您所需要的吗?在scala解释器中,这段代码可以工作,然后我切换到Intellij idea,即使我使用的是scala 2.11.8,我在“TermName”和“q”上也会出现编译错误。我应该为在IDE中使用scala宏做些特殊的事情吗?Hi@M.Rez宏不能是使用该宏的同一项目的一部分。你检查过这个项目以供参考吗?特别是,看看build.scala,解释器确实不需要单独的项目。但是编译器需要在解析代码之前在其上下文中添加宏,这就是为什么宏是一个单独的项目。请将该包提供给scala 2.13
val myInt = 3
assert("myInt" === nameOf(myInt))
val myInt = 3
assert("myInt" === "myInt")