2013-02-10 19 views
2

我是帶java背景的scala的新手。如何在繼承樹中構造匹配抽象父類的模式

有沒有一種方法模式匹配超級類(或特徵)的類繼承樹與葉作爲案例類和節點抽象類或特徵?據我所知,案例類繼承是不允許的。

我認爲,模式匹配大筆遺產樹的抽象類將是非常有益

在下面的代碼在比賽中陳述錯誤最後一種情況下編譯期間

sealed trait Person { 
    def name: String 
} 

case class Customer(name: String, email: String) extends Person 

sealed trait Employee extends Person { 
    def id: Int 
} 

case class Worker(name: String, id: Int, skills: Array[String]) extends Employee 

case class Manager(name: String, id: Int, title: String) extends Employee 

def process(p: Person) = p match { 
    case Customer(_, email) => email 
    case Employee(name, _) => name + "@acme.com" 
} 

回答

4

你失蹤在Employeename領域以及Employee同伴對象的unapply方法:

sealed trait Employee extends Person { 
    def id: Int 
    def name: String 
} 

object Employee { 
    def unapply(e: Employee): Option[(String, Int)] = 
    Option(e) map { e => 
     (e.name, e.id) 
    } 
} 

隨着上述變化的過程方法沒有問題:

def process(p: Person) = p match { 
    case Customer(_, email) => email 
    case Employee(name, _) => name + "@acme.com" 
} 
+0

這非常接近案例分類。但是,當我將'name'設置爲常量值時,模式匹配不起作用(例如:case Employee(「John」,_)=>「[email protected]」)。我的unapply方法可以支持這種過濾嗎? – Kostas 2013-02-12 00:54:04

+0

它應該已經工作。對我來說,它實際上是:'println(process(Worker(「Erik」,2,Array.empty)))'並且我在'process'中有這個:case Employee(「Erik」,_)=>「erik @ acme.com「' – EECOLOR 2013-02-12 07:18:43

+0

是的,它確實有效。謝謝! :) – Kostas 2013-02-13 00:45:27

1

這不是幻想(因爲其他人可能與結構類型的建議,),但它很實用,我想:

def process(p: Person) = p match { 
    case Customer(_, email) => email 
    case e: Employee => e.name + "@acme.com" 
} 

如果您需要到m ATCH對一些特定的已知值,你可以使用守衛:

def process(p: Person) = p match { 
    case Customer(_, email) => email 
    case e: Employee if e.name == "Joe" => e.name + "@acme.com" 
} 
+0

嗨,謝謝你的回覆。你的代碼解決了電子郵件的問題,但我正在尋找一種通用的方法。基本上我想以與案例類相似的方式進行模式匹配 – Kostas 2013-02-10 22:14:39