2012-08-22 57 views
3

CSplit和MapCanvT都是Scala Swing組件的子類型。因此,類型CanvNode始終是Component的子類型。我還沒有抓住Scala系列的功能性內容,但仍然喜歡摺疊。有什麼辦法可以減少這段代碼(除了把這個匹配放在一個函數中)並去除這些匹配嗎?Scala:訪問任何一個子類型

type CanvNode = Either[CSplit, MapCanvT] 

class CSplit(var s1: CanvNode, var s2: CanvNode) extends SplitPane 
{   
    topComponent = s1 match { case Left (s) => s; case Right (s) => s} 
    bottomComponent = s2 match { case Left (s) => s; case Right (s) => s} 

以上編譯。理想情況下,我只會寫:

type CanvNode = Either[CSplit, MapCanvT] 

class CSplit(var s1: CanvNode, var s2: CanvNode) extends SplitPane 
{   
    topComponent = s1 
    bottomComponent = s2 

但這不會編譯。

+0

這似乎是靜態類型的兩個'topComponent'和'bottomComponent'將是'CanvNode',因爲你不能在編譯時有什麼比賽表達式的值產生出來。你能否提供更多關於你想要完成的事情的信息? –

+0

@ConnorDoyle爲了清晰起見 –

回答

6

fold實際上會做你想在這裏。您也可以重寫此:

topComponent = s1 match { case Left (s) => s; case Right (s) => s} 

由於這樣的:

topComponent = s1.fold(identity, identity) 

而推斷出的類型將是最小上限的CSplitMapCanvT

Either還提供了寫這一個稍微更緊湊的方式:

topComponent = s1.merge 

通過隱式轉換到MergeableEither

+0

謝謝,我確信肯定會有一些更簡單的事情。 –

+0

例如,您可以看到[此答案](http://stackoverflow.com/a/11269221/334519),以獲取有關'Either'上的'fold'的更多信息。 –

0

爲什麼不把它作爲一個特質來區分呢?

sealed trait CanvNode 
class MapCanvT extends Component with CanvNode 
class CSplit extends SplitPane with CanvNode(var s1: CanvNode, 
              var s2: CanvNode) { 
    topComponent = s1 
    bottomCompoenent = s2 
} 
+0

由於MapCanvT不能從CanvNode繼承,因爲它的實現是獨立於此類定義的。可能它可以製作成CanvNode的一個類型類,但我認爲這和使用scala一樣複雜。 –