我正在尝试构建一个层次结构为Context
(保存不可变数据(和创建参与者处理数据的Module
层次结构的框架。Context
上的子类包含更多数据(例如,RemoteContext
将包含有关如何与远程主机通信的信息(。 还有Factory
对象来制作相关对象,这是Context
中数据的一部分。
我可以用子类定义层次结构,这工作正常。 定义完所有内容后,Mediator
对象通过传递上下文来初始化每个Module
。
下面的代码显示了该基本结构。
import java.{ util => ju}
trait Factory
trait Context[F <: Factory]
trait SomeContext[F <: Factory] extends Context[F]
trait MediatorModule[C <: Context[_ <: Factory]] {
def loadModule(c: C)
}
trait Mediator[C <: Context[Factory]] {
val context: C
def getModules: ju.List[MediatorModule[_ >: C]]
def run() = getModules.forEach(_.loadModule(context))
}
trait OtherFact extends Factory
trait OtherContext extends SomeContext[OtherFact]
class SomeModule extends MediatorModule[SomeContext[Factory]] {
def loadModule(c: SomeContext[Factory]): Unit = { }
}
class OtherModule extends MediatorModule[OtherContext] {
def loadModule(c: OtherContext): Unit = { }
}
class OtherContextImpl extends OtherContext {
}
class OtherMediator extends Mediator[OtherContext] {
val context: OtherContext = new OtherContextImpl
def getModules: ju.List[MediatorModule[_ >: OtherContext]] =
ju.Arrays.asList(new SomeModule,
new OtherModule)
}
(代码最初是用Java编写的,这就是为什么它使用Java列表(。
如前所述,这无法编译:
Test.scala:78:26: type mismatch;
[error] found : SomeModule
[error] required: MediatorModule[_ >: OtherContext]
[error] Note: SomeContext[Factory] <: Any (and SomeModule <: MediatorModule[SomeContext[Factory]]), but trait MediatorModule is invariant in type C.
[error] You may wish to define C as +C instead. (SLS 4.5)
[error] ju.Arrays.asList(new SomeModule,
[error] ^
[error] one error found
遵循编译器的建议,声明trait MediatorModule[+C <: Context[_ <: Factory]]
反而会给出两个错误:
Test.scala:52:20: covariant type C occurs in contravariant position in type C of value c
[error] def loadModule(c: C)
[error] ^
[error] Test.scala:75:29: type arguments [OtherContext] do not conform to trait Mediator's type parameter bounds [C <: Context[Factory]]
[error] class OtherMediator extends Mediator[OtherContext] {
[error] ^
我可以用trait Context[+F <: Factory]
修复一个,但 co/contra 变体错误仍然存在。
我该怎么做才能修复该错误? 另外,+C
如何转换回Java?
尝试使Context
和SomeContext
协变
trait Context[+F <: Factory]
trait SomeContext[+F <: Factory] extends Context[F]
然后代码编译。