синтаксис 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
}
}
2 ответов:
Пойдем туда шаг за шагом:
Оператор
|
в контексте сопоставления шаблонов позволяет определить альтернативные шаблоны в следующем виде:pattern1 | pattern2
Если вы хотите определить шаблон, соответствующий типу, этот шаблон должен быть представлен в следующем виде:
binding: Type
Предоставление выбора между двумя различными типами должно быть представлено в следующей форме:
binding1: Type1 | binding2: Type2
К привязка одного имени к двум альтернативным привязкам вы можете отказаться от имени отдельных Привязок (используя подстановочный знак
_
) и привязать имя общего шаблона к другой привязке с помощью оператора@
, как показано в следующем примере: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