首页 > 解决方案 > scala语法匹配多个案例类类型而不分解案例类

问题描述

我有各种案例类实现的密封特征。我想为同一个匹配表达式一次对多个类进行模式匹配。如果不分解案例类和“|”,我似乎无法做到这一点 它们之间

目前看起来像:

sealed trait MyTrait {
  val param1: String
  ...
  val param100: String
}

case class FirstCase(param1: String ...... param100: String) extends MyTrait
...
case class NthCase(param1: String ..... param100: String) extends MyTrait

代码中的另一个地方:

def myFunction(something: MyTrait) = {
   ...
   val matchedThing = something match {
      // this doesn't work with "|" character
      case thing: FirstCase | SecondCase => thing.param1
      ...
      case thing: XthCase | JthCase => thing.param10
   }
} 

标签: scalasyntaxpattern-matchingcase-class

解决方案


让我们一步一步地去那里:

  1. |模式匹配的上下文中,运算符允许您定义替代模式,格式如下:

    pattern1 | pattern2
    
  2. 如果要定义与类型匹配的模式,则必须以以下形式提供模式:

    binding: Type
    
  3. 然后应以以下形式提供两种不同类型之间的选择:

    binding1: Type1 | binding2: Type2
    
  4. 要将单个名称绑定到两个替代绑定,您可以丢弃单个绑定的名称(使用_通配符)并使用运算符将​​整个模式的名称绑定到另一个绑定@,如以下示例所示:

    binding @ (_ : Type1 | _ : Type2)
    

下面是一个例子:

sealed trait Trait {
  def a: String
  def b: String
}

final case class C1(a: String, b: String) extends Trait
final case class C2(a: String, b: String) extends Trait
final case class C3(a: String, b: String) extends Trait

object Trait {
  def f(t: Trait): String =
   t match {
    case x @ (_ : C1 | _ : C2) => x.a // the line you are probably interested in
    case y: C3 => y.b
  }
}

这是调用时的一些示例输出f

scala> Trait.f(C1("hello", "world"))
res0: String = hello

scala> Trait.f(C2("hello", "world"))
res1: String = hello

scala> Trait.f(C3("hello", "world"))
res2: String = world

您可以在 Scastie 上使用此处提供的示例。


推荐阅读