Scala:得到特质混合的类的名称

Ale*_*nov 6 scala traits

给定一个类的实例,我们显然可以返回它的名字:

trait MixedInClassDiscovery {
  val className = this.getClass.getName
}

class AClass extends MixedInClassDiscovery {
  ...
  this.className // returns "AClass"
  ...
}
Run Code Online (Sandbox Code Playgroud)

但这种方式使用反射,一次用于每个实例AClass.相反,每个班级都可以做一次吗?

我想到的一个解决方案是将它混合到伴随对象而不是类本身.

Rex*_*err 2

我想不出有什么方法可以在没有额外开销的情况下做到这一点。但是,您可以使用伴随对象以及一些额外的工作来完成此操作:

object Example {
  trait Discovery {
    def companion: Discovered
    def className: String = companion.className
  }
  trait Discovered extends Discovery {
    override lazy val className = {
      println("Getting class name!")  // To see how many times we're called
      this.getClass.getSuperclass.getName
    }
  }
  class Test extends Discovery {
    def companion = Test
  }
  object Test extends Test with Discovered {}
}
Run Code Online (Sandbox Code Playgroud)

在这里我们看到这是有效的:

scala> val a = new Example.Test
a: Example.Test = Example$Test@17e4c97

scala> val b = a.className
Getting class name!
b: String = Example$Test

scala> val c = a.className
c: String = Example$Test
Run Code Online (Sandbox Code Playgroud)

但这是有代价的:您不仅需要用 Discovery 来装饰类,还需要为每个类实现伴随方法并编写伴随对象(顺便说一句,不需要具有相同的名称)。