【发布时间】:2014-07-05 23:59:58
【问题描述】:
我有一个协变 Scala 类型 Thing[+B]。该实现使用内部可变队列:
private val queue : AsyncQueue[B]()
AsyncQueue 是一个自定义的可变队列实现,具有我无法在不可变版本中轻松实现的特殊属性。因为它是可变的,所以 AsyncQueue 是不变的。所以我不能在我的协变类型Thing中使用它。
由于queue 是私有的,我可以保证我的代码的正确性:例如我不会尝试将queue 分配给Queue[Any] 类型的引用。我怎样才能使这项工作,保持Thing 在B 中的协变,而不使用强制转换?
(使用强制转换的解决方案是声明一个AsyncQueue[Object] 并在入队/出队上强制转换对象,这非常难看。)
ETA:我了解类型协变,并且我了解为什么我不能声明协变类型的 AsyncQueue 或使 AsyncQueue 本身协变。我的问题是如何设计这段代码以避免到处使用强制转换。
【问题讨论】:
-
这听起来像是导致 java 泛型的设计者将变量声明放在使用对象的位置而不是声明它们的位置的确切用例。
-
Thing上有哪些方法利用了queue? -
AsyncQueue是一个基于 Future 的有界队列。一种方法调用queue.enqueue,它返回一个在项目入队时完成的Future(在队列中没有空间时等待)。另一个调用queue.dequeue,它返回一个Future,当一个项目出队时完成(队列为空时等待)。这些方法让我可以构建一个基于 Future 的状态机,它会在队列满时暂停。 -
进入
queue的Bs 来自哪里?你能举个例子说明你必须在哪里使用演员表吗? -
Bs 来自用户(即通过Thing的公共 API)并被推入队列。如果我声明一个AsyncQueue[AnyRef],那么我必须将出列值从AnyRef转换回B。