2017-04-12 79 views
0

如何從scala中的擴展類中獲取基類。實際上,我是Scala的新手,並嘗試使用密封特徵類編寫一些編碼。Scala中的密封特徵類轉換

例如,我有一個密封跟蹤類和一些案例類擴展到密封跟蹤類。

如:下列類型的

sealed trait Person 
case class Employer(name: String, id: Int, country: List[String]) extends Person 
case class Employee(name: String, id: Int) extends Person 

我期待例如:

type example1 = RDD[(String, Int, Person)] => RDD[((String, Int), Employee)] 

type example2 = RDD[(String, Int, List[Employer])] => RDD[((String, Int), List[Person])] 

對於例1:我想以下幾點:

def getType1(data: RDD[(String, Int, Person)]) = { 
    val res = data.map { 
     x => { 
     val emp = x._3.asInstanceOf[Employee] 
     ((x._1, X._2), Employee(emp.name, emp.id) 
     ) 
     } 
    } 
} 

但如何做反向對於類型example2? 一個例子會幫助我理解我的項目,請爲我提供建議。

+0

請注意,你的第一個例子是不安全的。如果人員不是員工,您將在運行時得到異常。你想用擁有僱主的記錄來做什麼? – puhlen

+0

此外,您已將僱主定義爲與國家/地區字段相同的類別,但正嘗試與員工一起使用,我認爲這是一個錯字,請修正它以避免混淆。 – puhlen

回答

1

您應該將返回類型註釋添加到您的方法中,它有助於清楚返回哪種類型,並且可以更輕鬆地控制類型,而不必將其留給推理器,因爲更改類型是你正在努力做什麼變得更加重要。

你的example1有幾個問題。首先,你沒有返回一個值,所以返回類型是單位,這不是你想要的。刪除val res =,以便返回地圖的結果。如果你添加了返回類型,編譯器可以爲你解決這個問題。如果還沒有處理RDD中的人員不是員工的情況,那麼您需要考慮在這種情況下應該怎麼做(過濾掉這些記錄或輸入一個默認值都是合理的選項,但您可能需要某些東西別的。

在示例2因爲你想要一個更一般的類型,你不需要做任何形式的檢查或澆注件。

def example2(data: RDD[(String, Int, List[Employer])]): RDD[((String, Int), List[Person])] = data.map { x => ((x._1, x._2), x._3)} 

發包方的人一個亞型,而list是協變,所以List [Employer]是List [Person]的子類型,因此您可以在需要List [Person]的任何位置使用List [Employer]。

+0

感謝您提供這些細節。我在實際編碼中解決了所有問題。 – sk1007

0

類似這對你有兩種數據類型:

def getType1(data: RDD[(String, Int, Person)]) : RDD[((String, Int),Person)] = { 
    data.map { case (s, i, person) => ((s, i), person)} 
}