2013-02-05 26 views
4

我試圖用新的關鍵字創建一個隊列..我爲可變和不可變隊列都做了這個。「new」關鍵字不能用於不可變的隊列

但是,當我用一成不變的隊列試過,提示錯誤:

<console>:8: error: constructor Queue in class Queue cannot be accessed in object $iw 
Access to protected constructor Queue not permitted because 
enclosing class object $iw in object $iw is not a subclass of 
class Queue in package immutable where target is defined 
     val a=new Queue[Int]() 
      ^

scala> import scala.collection.immutable.Queue 
import scala.collection.immutable.Queue 

scala> val a=new Queue[Int]() 
<console>:8: error: constructor Queue in class Queue cannot be accessed in object $iw 
Access to protected constructor Queue not permitted because 
enclosing class object $iw in object $iw is not a subclass of 
class Queue in package immutable where target is defined 
     val a=new Queue[Int]() 

但當我這個代碼與可變隊列,棧不變的,可變的堆棧...它運作良好

scala> import scala.collection.mutable.Queue 
import scala.collection.mutable.Queue 

scala> val a=new Queue[Int]() 
a: scala.collection.mutable.Queue[Int] = Queue() 



scala> import scala.collection.immutable.Stack 
import scala.collection.immutable.Stack 

scala> val a=new Stack[Int]() 
a: scala.collection.immutable.Stack[Int] = Stack() 


scala> import scala.collection.mutable.Stack 
import scala.collection.mutable.Stack 

scala> val a=new Stack[Int]() 
a: scala.collection.mutable.Stack[Int] = Stack() 

誰能告訴我,爲什麼這樣?

+0

隊列和大多數其他集合構造函數隱藏在標準庫中。相反,您應該使用工廠方法,例如'Queue [Int]()'或'Queue.empty [Int]'**,而不使用** new關鍵字。這是設計選擇。 –

+2

但我想知道這個原因,爲什麼只有不可變隊列,可變隊列,這是好的。 – Rishi

回答

4

從快看,我敢說不可改變的版本是通過一對夫婦的List S的轉動需要基本實現在之間給出不錯的表現寫入(隊列/出隊)。

這與其他收藏很不一樣,因爲它需要提到List s作爲class構造函數的參數。
另一方面,伴侶對象通過接受Queue內容的可變數目的初始值,提供與其他集合一致的公共工廠方法。

缺少的是該類的公共構造方法,它將通過獲取初始值並使用它們構建「enque/dequeue」Lists來模仿伴隨對象apply調用。

也許它不被認爲是必要的,或者它是一個疏忽,或者有一個更深的問題,我不明白。

3

編譯器已經告訴你它爲什麼不起作用,因爲析取器是protected。你必須使用配套的apply方法來創建一個immutable.Queue:在sourcecode

val queue = immutable.Queue(1,2,3) 
+0

但我想知道這是爲什麼它只與不可變隊列,可變隊列,這是很好的原因... – Rishi

+0

是的。我認爲這是真正的問題 –

+1

我認爲你只能從scala傢伙那裏得到明確的答案,所以我建議你在他們的郵件列表上提問。 – drexin

1

我會將問題解釋爲「爲什麼構造函數受到保護」。 我們只能猜測,但我傾向於認爲這是一個簡單的疏忽。 作爲一種風格問題,使用伴隨對象來實例化集合通常會更好,但是假設您也可以直接實例化其他具體集合,則這應該與Queue一致。換句話說,我絕對認爲Queue應該有這個沒有ARG構造器創建一個空的隊列中,如果僅僅作爲一致性的問題:

class Queue[+A] extends ... { 
    ... 
    def this() { this(Nil, Nil) } 
    ... 
} 

這是非常主觀的,但。

0

我想這是因爲鼓勵使用empty來創建void immutable集合,因爲它避免了開銷(如果你多次這樣做)並最大限度地利用不可變性。每一次都不需要創建新實例,因爲「世界上只有一個空隊列」。對於可變集合,顯然這不起作用。