在Scala中,如何获取“对象”的*名称*(不是类的实例)?

22

在Scala中,我可以这样声明一个对象:

class Thing

object Thingy extends Thing

我该如何在Scala中获取"Thingy"(对象的名称)?

我听说Lift(Scala的Web框架)可以做到这一点。


你不是已经有变量名了吗?为什么你还要这样做呢? - Shaheer
请参见以下内容:https://dev59.com/YG445IYBdhLWcg3wE2Tw - Shaheer
1
@Shaheer 一个对象不是一个变量。你可能有些困惑了。当一个变量指向一个对象时,变量的名称并不等同于对象的名称。 - Robin Green
4个回答

32

如果你将它声明为一个case object而不仅仅是一个object,那么它将自动扩展Product trait,并且你可以调用productPrefix方法来获取对象的名称:

scala> case object Thingy
defined module Thingy

scala> Thingy.productPrefix
res4: java.lang.String = Thingy

我喜欢它简单易用的特点和标准API。然而,不幸的是,据我所知,该产品不能保证它总是只是实现它的对象的名称。 - Wilfred Springer

24

只需获取类对象,然后获取其名称。

scala> Thingy.getClass.getName
res1: java.lang.String = Thingy$

现在只需删除$即可。

编辑:

要删除封闭对象的名称和结尾的$,只需执行以下操作即可。

res1.split("\\$").last

5
如果对象定义在其他对象或方法中,它也可以是test.Main$Thingy$或test.Main$Test1$2$。 - Sergey Passichenko
@SergeyPassichenko:那么你需要进行更多的解析才能获取值,但基本思路是相同的。 - Kim Stebel
@SergeyPassichenko:在答案中包含了一个解决方案。它没有涵盖在方法中定义的对象,但那通常不是必需的。 - Kim Stebel
这里还有一个奇怪的地方。Thingy.getClass.getName => "Thingy$",但是 println(Thingy.getClass.getName) 打印出 "$line2.$read$$iw$$iw$Thingy$"。有人能解释一下吗? - Scoobie
@Scoobie:那只会在REPL中发生。 - Kim Stebel
7
在2.10版本中,您可以这样做:scala> object Foo 定义了名为Foo的模块 scala> import scala.reflect.runtime.universe._ 导入了scala.reflect.runtime.universe._库 scala> typeOf[Foo.type].termSymbol.name res0: reflect.runtime.universe.Name = Foo - Eugene Burmako

3
我不知道哪种方式是正确的,但这可以通过Scala反射实现:
implicitly[TypeTag[Thingy.type]].tpe.termSymbol.name.toString

0
def nameOf[T](implicit ev: ClassTag[T]):String = ev.runtimeClass.getName.replace("$", "")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接