синтаксис Scala, чтобы соответствовать на несколько типов классов без разложения в случае класса [дубликат]



На этот вопрос уже есть ответ здесь:



У меня есть запечатанная черта с различными реализациями класса case. Я хочу, чтобы шаблон совпадал на нескольких классах сразу для одного и того же выражения соответствия. Я не могу сделать это, не разложив классы case и " | " между ними



В настоящее время выглядит так:



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

2 ответов:

Пойдем туда шаг за шагом:

  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.

Это сработало для меня 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")
}

Comments

    Ничего не найдено.