如何使用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)
}
}
答案 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_id
或ElasticSource
的值。因此,您需要使用sourceType
创建一个函数,该函数将在您知道这些值后返回适当的类:
val builder = sourceType match {
case "elastic" =>
(id: String, source: ElasticSource) => ElasticElement(id, source)
case "csv" =>
(id: String, source: ElasticSource) => CsvElement(id, source)
}
当您知道queryId
和source
时,可以使用builder
创建您的元素:
val element: Element = builder(queryId, source)
此element
可以是ElasticElement
或CsvElement
,具体取决于先前给出的sourceType
的值。您可以使用match
确定其中之一:
element match {
case e: ElasticElement =>
println(e.elastic_source)
case e: CsvElement =>
println(e.csv_source)
}