在 Scala 中混合逆变和协变类型



我正在尝试构建一个层次结构为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?

尝试使ContextSomeContext协变

trait Context[+F <: Factory]
trait SomeContext[+F <: Factory] extends Context[F]

然后代码编译。

相关内容

  • 没有找到相关文章

最新更新