2

我有一个特征,它的初始化本质上不是线程安全的,而是严格用作伴生对象的基础,根据定义,初始化线程安全的。

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

4

2 回答 2

5

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

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

object Bar extends Foo

如果你需要几个对象来扩展它,你可以尝试基于Singleton魔法类型的东西:

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

但我不知道这是否有效。

于 2015-01-10T05:32:05.547 回答
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
}
于 2015-01-10T03:33:05.030 回答