如何使用case..match在Scala中定义案例类?

时间:2018-10-15 19:18:00

标签: scala

如何使用case..match在Scala中定义案例类?

sourceType match {
  case "elastic" => {
    case class Element(query_id: String,
                       elastic_source: ElasticSource)
  }
  case "csv" => {
    case class Element(query_id: String,
                       csv_source: ElasticSource)
  }
}

2 个答案:

答案 0 :(得分:2)

我认为您在做什么是不可能的。您必须先定义案例类,然后再使用它。要添加变体,您可以使用Enumeration或定义不同的case类(也许扩展基本的'Element'类)。这将是众多可能性中的一种:

object SourceType extends Enumeration {
    type SourceType = Value
    val Csv, Elastic = Value
}
case class Element(query_id: String, source: ElasticSource, `type`: SourceType)

// then you can do sth like this: 
val yourElement = Element(query_id, elastic_source, 
   sourceType match {
      case "elastic" => SourceType.Elastic
      case "csv" => SourceType.Csv
      case _ => // do sth else
})

答案 1 :(得分:1)

这是不可能的,因为案例类是类型,并且所有类型都是在编译时而不是运行时定义的。您在运行时所能做的就是在不同类型之间进行选择。与您描述的最接近的涉及到预先创建两个案例类:

sealed trait Element
case class ElasticElement(query_id: String, elastic_source: ElasticSource) extends Element
case class CsvElement(query_id: String, csv_source: ElasticSource) extends Element

您的代码根据sourceType在这些选项之间进行选择,但是从您的注释中,您现在还不知道query_idElasticSource的值。因此,您需要使用sourceType创建一个函数,该函数将在您知道这些值后返回适当的类:

val builder = sourceType match {
  case "elastic" =>
    (id: String, source: ElasticSource) => ElasticElement(id, source)
  case "csv" =>
    (id: String, source: ElasticSource) => CsvElement(id, source)
}

当您知道queryIdsource时,可以使用builder创建您的元素:

val element: Element = builder(queryId, source)

element可以是ElasticElementCsvElement,具体取决于先前给出的sourceType的值。您可以使用match确定其中之一:

element match {
  case e: ElasticElement =>
    println(e.elastic_source)
  case e: CsvElement =>
    println(e.csv_source)
}