【问题标题】:Sealed trait class conversion in ScalaScala中的密封特征类转换
【发布时间】:2017-09-08 16:14:31
【问题描述】:

如何从 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 类型如何做相反的事情呢? 一个例子将帮助我理解我的项目,请给我建议。

【问题讨论】:

  • 请注意,您的第一个示例并不安全。如果 Person 不是 Employee,您将在运行时收到异常。您想对包含 Employer 的记录做什么?
  • 另外,您已将 Employer 定义为具有 country 字段的类,但尝试与 Employee 一起使用,我认为这是一个错字,请修正它以避免混淆。

标签: java scala


【解决方案1】:

您应该将返回类型注释添加到您的方法中,它有助于明确返回的类型,并让您更好地控制类型,而不是将其留给推理器,因为更改类型是返回的重要部分你正在努力做到这一点变得更加重要。

您的 example1 有几个问题。首先,您没有返回值,因此返回类型是 Unit,这不是您想要的。删除 val res = 以便返回映射的结果。如果您添加了返回类型,编译器可以为您捕获它。如果也不能处理来自 RDD 的 Person 不是 Employee 的情况,您需要考虑在这种情况下该怎么做(过滤掉这些记录或输入默认值都是合理的选择,但您可能想要一些东西否则。

在示例 2 中,因为您想要一个更通用的类型,所以您不需要进行任何类型的检查或强制转换。

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

Employer 是 person 的子类型,List 是协变的,因此 List[Employer] 是 List[Person] 的子类型,因此您可以在任何需要 List[Person] 的地方使用 List[Employer]。

【讨论】:

  • 感谢您提供此类详细信息。我修复了实际编码中的所有问题。
【解决方案2】:

这两种数据类型都适用于你:

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

【讨论】:

    猜你喜欢
    • 2015-05-26
    • 1970-01-01
    • 2015-09-17
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 2018-12-18
    相关资源
    最近更新 更多