2017-04-12 82 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)} 
}