特征能否保证它在编译时或 运行 时被伴随对象继承
Can a trait guarantee that it is inherited by a companion object at compile- or run-time
我有一个特性,初始化不是本质上线程安全的,但严格用作伴随对象的基础,初始化是 线程安全的定义。
有什么方法可以保证(在编译时或 运行 时)特性总是由伴生对象扩展吗?该特征有一个方法,该方法始终且仅在伴随对象初始化期间调用,这可能是验证的地点。
以下解决方案检查子 class 的构造函数的数量,它基于对象具有 0 个构造函数而 classes 至少有 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
}
如果 trait 必须恰好扩展 1 个对象,您可以在编译时这样检查它:
trait Foo { this: Bar.type =>
...
}
object Bar extends Foo
如果你需要多个对象来扩展它,你可以尝试基于Singleton
魔法类型的东西:
trait Foo { this: Singleton =>
...
}
但我不知道这是否有效。
我有一个特性,初始化不是本质上线程安全的,但严格用作伴随对象的基础,初始化是 线程安全的定义。
有什么方法可以保证(在编译时或 运行 时)特性总是由伴生对象扩展吗?该特征有一个方法,该方法始终且仅在伴随对象初始化期间调用,这可能是验证的地点。
以下解决方案检查子 class 的构造函数的数量,它基于对象具有 0 个构造函数而 classes 至少有 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
}
如果 trait 必须恰好扩展 1 个对象,您可以在编译时这样检查它:
trait Foo { this: Bar.type =>
...
}
object Bar extends Foo
如果你需要多个对象来扩展它,你可以尝试基于Singleton
魔法类型的东西:
trait Foo { this: Singleton =>
...
}
但我不知道这是否有效。