2013-01-07 64 views
4

是否有任何理由爲什麼collection.mutable.Queuecollection.mutable.PriorityQueue在Scala標準庫中不共享類似QueueLike基礎特徵?方法似乎具有相同的簽名。爲什麼這些類不能作爲隊列容器互換,還是我錯過了一些東西?斯卡拉隊列和PriorityQueue基礎特徵

+0

您使用的是什麼版本的Scala?我檢查了2.10,2.9,2.8和2.7 API文檔,沒有一個具有QueueLike特性。如果問題是關於可以由不可變和可變實現共享的常見QueueLike特性的_concept_,那麼存在一個問題:可變類在其包含的類型參數中都是不變的。不可變集合類在它們包含的類型參數中都是協變的。涉及包含類型值的任何API元素都不能由不可變和可變實現共享。 –

回答

1

也許這真不愧是一個答案,而不僅僅是一個評論...

什麼版本的斯卡拉您使用的是?我檢查了2.10,2.9,2.8和 2.7 API文檔,沒有一個具有QueueLike特性。如果問題是關於一個常見QueueLike特徵的概念,它可以由不可變和可變實現共享,那麼就存在一個問題:可變類在其包含的類型參數中都是不變的。不可變集合類在它們包含的類型參數中都是協變的。任何涉及包含類型值的API成員,無論作爲參數還是返回類型,都不能由不可變和可變實現共享。

第二回合:

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) 
    } 
} 

在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 

但是,你會發現,書面,只有兩件事情,你可以從UniQueue返回的值做.apply(),那就叫enqueuedequeu。你必須複製你想使用的所有其他方法簽名到trait QueueOps[T],如果有任何變體簽名,你將無法做到這一點。

+0

請看這個問題 - 我只談論可變版本。基本上,我想有一個工廠對象,它返回一個'PriorityQueue'或一個簡單的'隊列'基於一些傳遞的參數。所以返回類型應該是兩者的統一。從我看到的統一導致像'Seq'這樣的事情,這對我來說很奇怪,因爲我需要一些具有'enqueue'和'dequeue'方法的基類型。我希望這是有道理的。 –