特征是否可以保证它在编译或运行时由伴随对象继承

时间:2015-01-10 03:07:27

标签: scala traits companion-object

我有一个特性,初始化本质上是线程安全的,但是它主要用作伴随对象的基础,初始化线程 - 按定义安全。

是否有某种方法可以保证(在编译或运行时)特征始终由伴随对象扩展?该特征具有一种方法,该方法始终仅在伴随对象初始化期间被调用,该方法可以是验证的站点。

2 个答案:

答案 0 :(得分:5)

如果特征必须由1个对象扩展,您可以在编译时检查它,如下所示:

trait Foo { this: Bar.type =>
  ...
}

object Bar extends Foo

如果您需要多个对象来扩展它,您可以尝试基于Singleton魔法类型的内容:

trait Foo { this: Singleton =>
  ...
}

但我不知道这是否有效。

答案 1 :(得分:1)

以下解决方案检查子类的构造函数的数量,它基于观察到对象具有0个构造函数,而类具有至少1个。

检查在运行时发生。

trait Y {
  // objects have 0 constructors, everything else has >= 1 constructors
  require(getClass.getConstructors.length == 0, "Trait Y should be extended by objects only")

  def hello(): Unit
}

class Foo$ extends Y {
  def hello() = println("Hello Foo$")
}

class Foo extends Y {
  def hello() = println("Hello Foo")
}

object Bar extends Y {
  def hello() = println("Hello Bar")
}

object Test extends App {
  new Foo().hello()  // exception is thrown
  new Foo$().hello()  // exception is thrown
  Bar.hello()  // prints Hello Bar
}