2011-11-07 51 views
11

通過在ObservableSetHashSet中混合創建了一個新類型,我期待替換,然後可以使用新類型創建新類型如下面的「foo」中的實例。但是這不能編譯,雖然使用原始的長整型看起來很好(如下面的「bar」所示)。創建類型別名的實例會導致「需要類的類型」錯誤

這只是語言的一個特徵,或者我做了一些愚蠢的事情?

package whatever 

import collection.mutable._ 
object Whatever { 

    type ObservableHashSet[T] = HashSet[T] with ObservableSet[T] 
    class X 


    def foo { 
     new ObservableHashSet[X] 
    } 

    def bar { 
    new HashSet[X] with ObservableSet[X] 
    } 
} 

的錯誤是..

error: class type required but scala.collection.mutable.HashSet[scala.Whatever.X] with scala.collection.mutable.ObservableSet[scala.Whatever.X] found 
new ObservableHashSet[X] 

回答

13

簡要版本是,你已經創建了一個類型別名結構類型(你不能實例化)。

這是你做了什麼的簡化版本(不工作):

scala> import collection.mutable._ 
import collection.mutable._ 

scala> type ObservableHashSet[T] = HashSet[T] with ObservableSet[T] 
defined type alias ObservableHashSet 

scala> new ObservableHashSet[String] 
<console>:12: error: class type required but scala.collection.mutable.HashSet[String] with scala.collection.mutable.ObservableSet[String] found new ObservableHashSet[String] 

現在,錯誤確實讓一些感覺,讓我嘗試解釋爲什麼。

使用type ObservableHashSet[T] = HashSet[T] with ObservableSet[T]您正在爲非具體類型的東西定義類型別名(或者,如錯誤消息所述,不是「類類型」),因此您無法使用new創建它的實例。

但是,這(與我們開展創建一個類類型的中間步驟)的工作原理:

scala> class ObservableHashSet[T] extends HashSet[T] with ObservableSet[T] 
defined class ObservableHashSet 

scala> type obs[T] = ObservableHashSet[T] 
defined type alias obs 

scala> new obs[String] 
res1: ObservableHashSet[String] = Set() 

所以,問題是:爲什麼斯卡拉讓你創建一個類型別名,你不能實例化? 那麼,type ObservableHashSet[T] = HashSet[T] with ObservableSet[T]是一個結構類型。雖然,正如您在第一段代碼中看到的那樣,您無法創建它的實例,但仍然可以使用它:例如對一個函數的參數進行結構約束。

請看:

scala> type ObservableHashSet[T] = HashSet[T] with ObservableSet[T] 
defined type alias ObservableHashSet 

scala> def test(obsHashSet: ObservableHashSet[String]) : String = {"bingo!"} 
test: (obsHashSet: ObservableHashSet[String])String 

scala> test(new HashSet[String] with ObservableSet[String]) 
res4: String = bingo! 

但如果我們試圖調用測試與不符合結構類型,我們得到一個類型不匹配的參數:

scala> test(new HashSet[String]) 
<console>:13: error: type mismatch; 
found : scala.collection.mutable.HashSet[String] 
required: ObservableHashSet[String] 
+0

感謝保羅。我想我正在考慮「類型」作爲一種宏觀替代。我會更多地閱讀一些結構類型。 thx – Richard

+0

@Richard:謝謝你的提問。在你問及試驗「類型」是否有啓發性之前,我不知道答案。 –

相關問題