代码之家  ›  专栏  ›  技术社区  ›  ScalaBoy

如何使用case..match在scala中定义case类?

  •  1
  • ScalaBoy  · 技术社区  · 6 年前

    如何使用case..match在scala中定义case类?

    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 回复  |  直到 6 年前
        1
  •  2
  •   Florian Baierl    6 年前

    我不认为你在做什么。您必须先定义case类,然后再使用它。要添加变体,可以使用枚举或定义不同的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
    })
    
        2
  •  1
  •   Tim    6 年前

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

    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 在这一点上。所以你需要使用 源类型 要创建一个函数,一旦知道这些值,它将返回适当的类:

    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 与be-either ElasticElement CsvElement 取决于 源类型 之前给出的。您可以通过使用 match :

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