Is there any reason why collection.mutable.Queue
and collection.mutable.PriorityQueue
don't share something like QueueLike
base trait in the Scala standard library ? The enqueue
& dequeue
methods appear to have the same signatures. Why aren't the classes interchangeable as queue containers, or am I missing something ?
Perhaps this deserves to be an answer, not just a comment...
What version of Scala are you using? I checked the 2.10, 2.9, 2.8 and 2.7 API docs and none of them have a QueueLike
trait. If the question is about the concept of a common QueueLike
trait that could be shared by both immutable and mutable implementations, there's a problem: Mutable classes are all invariant in their contained type parameters. The immutable collection classes are all covariant in their contained type parameter. Any API member that involves values of the contained type, whether as arguments or a return type, cannot be shared by both immutable and mutable implementations.
Round Two:
package rrs.scribble
import scala.collection.mutable.{Queue, PriorityQueue}
import scala.math.Ordering
trait QueueOps[T]
{
def dequeue(): T
def enqueue(elems: T*): Unit
}
object UniQueue
{
sealed trait QSel
object PrioQ extends QSel
object PlainQ extends QSel
def apply[T : Ordering](kind: QSel): QueueOps[T] =
kind match {
case PrioQ => new PriorityQueue[T]() with QueueOps[T]
case PlainQ => new Queue[T]() with QueueOps[T]
}
}
object UQTest
{
import UniQueue._
def main(args: Array[String]) {
val prq1 = UniQueue[Int](PrioQ)
val plq1 = UniQueue[Int](PlainQ)
prq1.enqueue(1, 4, 9)
plq1.enqueue(9, 4, 1)
val prq2 = UniQueue[Int](PrioQ)
val plq2 = UniQueue[Int](PlainQ)
printf("prq1: dequeue=%d; dequeue=%d; dequeue=%d%n", prq1.dequeue, prq1.dequeue, prq1.dequeue)
printf("plq1: dequeue=%d; dequeue=%d; dequeue=%d%n", plq1.dequeue, plq1.dequeue, plq1.dequeue)
prq2.enqueue(9, 4, 1)
plq2.enqueue(1, 4, 9)
printf("prq2: dequeue=%d; dequeue=%d; dequeue=%d%n", prq2.dequeue, prq2.dequeue, prq2.dequeue)
printf("plq2: dequeue=%d; dequeue=%d; dequeue=%d%n", plq2.dequeue, plq2.dequeue, plq2.dequeue)
}
}
Running this in SBT:
> run
[info] Running rrs.scribble.UQTest
prq1: dequeue=9; dequeue=4; dequeue=1
plq1: dequeue=9; dequeue=4; dequeue=1
prq2: dequeue=9; dequeue=4; dequeue=1
plq2: dequeue=1; dequeue=4; dequeue=9
However, you'll find that as written, there are only two things you can do with the value returned from UniQueue.apply() and that is call enqueue
and dequeu
. You have to copy every other method signature you want to be able to use to trait QueueOps[T]
and if there are any with variant signatures you won't be able to do that.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.