简体   繁体   中英

How to define case class in Scala using case..match?

How do I define case class in Scala using case..match?

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

I don't think what you are doing is possible. You have to define the case class first and use it afterwards. To add variation you could use an Enumeration or define different case classes (maybe extending a base 'Element' class). This would be one - of many - possibilities:

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
})

This is not possible because case classes are types, and all types are defined at compile time not run time. All you can do at run time is choose between different types. The closest to what you describe involves creating the two case classes in advance:

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

Your code decides between these to options based on sourceType , but from your comments you don't know the value of query_id or the ElasticSource at this point. So you need to use sourceType to create a function that will return the appropriate class once you know these values:

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

When you know the queryId and source , you can use the builder to create your element(s):

val element: Element = builder(queryId, source)

This element with be either ElasticElement or CsvElement depending on the value of sourceType given earlier. You can determine which one of these you have by using match :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM