2015-02-10 25 views
0

我對scala非常陌生,我來自Obj-C,所以我對泛型不太熟悉。這是我在做什麼:無法找出泛型的東西

class A[T <: Word](rules: Map[T, T]) { 
    def this(rulesStr: Map[String, String], i:Int) = { 
    this(rulesStr map { case (k, v) => (new W(k), new W(v))}) 
    } 
} 

所以,我試圖重拍我的地圖,從(字符串,字符串)到(W,W)。 W是基礎字符串類,並擴展了Word。下面是它的定義

class W(val underlying: String) extends Word 

我收到提示:

Error:(6, 19) type mismatch; 
found : scala.collection.immutable.Map[W,W] 
required: Map[T,T] 
this(rulesStr map { case (k, v) => (new W(k), new W(v))}) 
      ^

我想不通,我在做什麼錯,因爲W¯¯繼承詞,它是滿足的T要求。

在此先感謝!

回答

2

問題是,您需要一個Map[T, T]用於客戶選擇的任何T,這是因爲您構建的是Map[W, W],所以您不能這樣做。例如,如果有人定義

case class OtherWord(s: String) extends Word 

那麼他們就應該能夠使用A因爲OtherWord滿足制約T

val a = A[OtherWord](...) 

,並在這種情況下,你會路過這裏需要Map[OtherWord, OtherWord]一個Map[Word, Word]

您可以刪除類型參數:

class A(rules: Map[W, W]) { 
    def this(rulesStr: Map[String, String], i:Int) = { 
    this(rulesStr map { case (k, v) => (new W(k), new W(v))}) 
    } 
} 

或需要String => T函數構造

class A[T <: Word](rules: Map[T, T]) { 
    def this(rulesStr: Map[String, String], i:Int, f: String => T) = { 
    this(rulesStr map { case (k, v) => (f(k), f(v))}) 
    } 
} 
+0

事情是可以提供,我不想用戶選擇'T',如果他使用替代構造函數。其實,除了那張地圖之外,我不需要那種類型。我只想確保,地圖的關鍵和價值將會擴展'Word'。有可能以其他方式做到嗎? – 2015-02-10 20:15:03

+0

@AlfredZien - 如果用戶不能選擇'T',那麼您根本不需要泛型 - 因爲您使用'W',那麼您知道地圖中的鍵/值類型會擴展'Word', W'確實。 – Lee 2015-02-10 20:20:41

+0

明白了。我可以寫'A類(規則:地圖[Word,Word])',不需要泛型。謝謝!仍然與靜態類型和多重繼承混淆。 – 2015-02-10 20:28:49

相關問題