首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Scala中混合逆变和协变类型

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

Stack Overflow用户
提问于 2019-09-25 23:24:18
回答 1查看 136关注 0票数 0

我正在尝试构建一个由Context(包含不可变数据)和Module组成的层次结构的框架,这些actors创建了处理数据的actors。Context上的子类包含更多数据(例如,RemoteContext将包含有关如何与远程主机通信的信息)。也有Factory对象来生成相关对象,这些对象是Context中数据的一部分。

我可以用子类定义层次结构,这很好用。一旦定义了所有内容,Mediator对象就会通过传递上下文来初始化每个Module

下面的代码显示了该基本结构。

代码语言:javascript
复制
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列表的原因)。

正如所写的,这无法编译:

代码语言:javascript
复制
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]]会产生两个错误:

代码语言:javascript
复制
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/对数变量错误仍然存在。

我能做些什么来修复这个错误呢?另外,+C如何转换回Java?

EN

回答 1

Stack Overflow用户

发布于 2019-09-26 00:48:59

尝试使ContextSomeContext成为协变

代码语言:javascript
复制
trait Context[+F <: Factory]

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

然后编译代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58101798

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档