2013-02-13 81 views
0

我想在Scala中做一些我不太確定的事情。我喜歡來自社區的一些反饋。協調多個通用構造函數的參數

說我有一些「東西」密封的特點,它的一些具體的擴展,並與該性狀一些執行工作的泛型類..

sealed trait Thing 
class CoolThing extends Thing 
class OtherThing extends Thing 

class BoxOfThings[T <: Thing] 

現在,我可以定義另一個類處理,像這樣兩個人的事情盒子'..

class PairOfBoxes(boxOne: BoxOfThings[_ <: Thing], boxTwo: BoxOfThings[_ <: Thing]) 

然而,這裏是完美的罰款創造PairOfBoxesCoolThing■一個盒子和其他的OtherThing秒。我想聲明boxOneboxTwo包含相同類型的Thing ..是不是可能?

例如:

// Cool things.. 
val boxOfCoolThings = new BoxOfThings[CoolThing] 
val anotherBoxOfCoolThings = new BoxOfThings[CoolThing] 
// Other things.. 
val boxOfOtherThings = new BoxOfThings[OtherThing] 

// A pair of cool boxes, no problem: 
new PairOfBoxes(boxOfCoolThings, anotherBoxOfCoolThings) 

// A pair of different boxes, compiles but I don't want it to: 
new PairOfBoxes(boxOfOtherThings, anotherBoxOfCoolThings) 

我可以通過使PairOfBoxes通用本身,像這樣做..

class TypedPairOfBoxes[T <: BoxOfThings[_ <: Thing]](boxOne: T, boxTwo: T) 

它的工作原理,但它的醜陋..

// A pair of cool boxes, no problem: 
new TypedPairOfBoxes[BoxOfThings[CoolThing]](boxOfCoolThings, anotherBoxOfCoolThings) 

// A pair of different boxes, doesn't compile: 
val mixedPair = new TypedPairOfBoxes[BoxOfThings[CoolThing]](boxOfOtherThings, anotherBoxOfCoolThings) 

我想避免這是我可以。它將問題推向上游並迫使我們指定每個TypedPairOfBoxes的內容。簡單地使用一個無類型的PairOfBoxes將是理想的,它斷言它的參數是相同的類型。

可能嗎?

謝謝!

回答

1

你只需要爲寫:

class TypedPairOfBoxes[T <: Thing](one: BoxOfThings[T], two: BoxOfThings[T]) 

然後:

scala> new TypedPairOfBoxes(boxOfOtherThings, anotherBoxOfCoolThings) 
<console>:15: error: type mismatch; 
found : BoxOfThings[OtherThing] 
required: BoxOfThings[Thing] 
Note: OtherThing <: Thing, but class BoxOfThings is invariant in type T. 
You may wish to define T as +T instead. (SLS 4.5) 
       new TypedPairOfBoxes(boxOfOtherThings, anotherBoxOfCoolThings) 
           ^
<console>:15: error: type mismatch; 
found : BoxOfThings[CoolThing] 
required: BoxOfThings[Thing] 
Note: CoolThing <: Thing, but class BoxOfThings is invariant in type T. 
You may wish to define T as +T instead. (SLS 4.5) 
       new TypedPairOfBoxes(boxOfOtherThings, anotherBoxOfCoolThings) 
                ^

scala> new TypedPairOfBoxes(boxOfCoolThings, anotherBoxOfCoolThings) 
res3: TypedPairOfBoxes[CoolThing] = [email protected] 
+0

非常好,請你提供一個解釋爲什麼這個工作原理? – 2013-02-13 11:03:43

0

我< 3斯卡拉

斯卡拉可以推斷出通用類型,這樣我可以定義一個「醜」類型類,但並不需要的時候我用它來指定具體實施。

有了這個認識,我能夠定義一個類似於上面我的問題類型類..

class TypedPairOfBoxes[T, BoxOfThings[T <: Thing]](boxOne: BoxOfThings[T], boxTwo: BoxOfThings[T])

..它看起來有點粗糙,但可以作爲簡單的這個:

// Both boxes contain cool things, no problem: 
new TypedPairOfBoxes(boxOfCoolThings, anotherBoxOfCoolThing) 

// These boxes contain different things, doesn't compile: 
new TypedPairOfBoxes(boxOfOtherThings, anotherBoxOfCoolThing) 

令人驚歎。

編輯:

作爲@Eastsun證實,的一般定義的後半部分是未使用的。所以可以這樣寫:

class TypedPairOfBoxes[T <: Thing](boxOne: BoxOfThings[T], boxTwo: BoxOfThings[T]) 

這看起來非常像Java。但令人驚奇的是Scala從參數中推斷出泛型。

+0

我要離開這個開一會兒。這可以做得更乾淨嗎? – 2013-02-13 00:28:09

相關問題