在不分解大小写 class 的情况下匹配多个大小写 class 类型的 Scala 语法

scala syntax to match on multiple case class types without decomposing the case class

我有一个 sealed trait 有各种 case class 实现。我想一次在多个 classes 上对同一个匹配表达式进行模式匹配。如果不分解案例 classes 和“|”,我似乎无法做到这一点他们之间

目前看起来像:

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

这对我有用 https://scastie.scala-lang.org/pT4euWh6TFukqiuPr4T6GA:

sealed trait Sup {
  def a: String
  def i: Int
}

case class First(a: String, i: Int, d: Double) extends Sup

case class Second(a: String, i: Int, x: Seq[Double]) extends Sup

case class Third(a: String, i: Int, c: Char) extends Sup

val sups = Seq(First("s", 1, 1.0), Second("s", 4, Seq(1.1)), Third("s", 4, 'f'))

sups.foreach {
  case _: First | _: Second => println("ffff")
  case _                    => println("ggg")
}

让我们一步一步来:

  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

您可以尝试提供的示例 here on Scastie