Я пытаюсь построить каркас с иерархией 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?