Чтобы ответить на исходный вопрос, сопоставление с образцом эффективно переводится в серию операторов if / else, просто в серию тестов. case _
в конце - просто прорыв (без связанного теста). Таким образом, существует очень небольшая разница между наличием A, B и C в одном совпадении и A и B в совпадении, а затем делегированием в другое совпадение, которое соответствует C. Используя следующее в качестве примера:
class T
case class A(v: Int) extends T
case class B(v: Int) extends T
case class C(v: Int) extends T
class Foo {
def getOperation(t: T): Unit = {
t match {
case A(2) => println("A")
case B(i) => println("B")
case _ => unknownOperation(t)
}
}
def unknownOperation(t: T): Unit = println("unknown operation t=" + t)
}
class Bar extends Foo {
override def unknownOperation(t: T): Unit = t match {
case C(i) => println("C")
case _ => println("unknown operation t=" + t)
}
}
Используя jad для декомпиляции Foo.class, мы получаем:
public void getOperation(T t) {
label0:
{
T t1 = t;
if(t1 instanceof A)
{
if(((A)t1).v() == 2)
{
Predef$.MODULE$.println("A");
break label0;
}
} else
if(t1 instanceof B)
{
Predef$.MODULE$.println("B");
break label0;
}
unknownOperation(t);
}
}
Итак, я бы сказал, что вам не стоит беспокоиться о производительности [*].
Однако, с точки зрения дизайна, я бы, вероятно, немного поменял вещи и либо использовал шаблон Command, как предлагает Фрэнк, либо вместо переопределения unknownOperation
в подклассе, вы могли бы переопределить getOperation
, что делает совпадение с C и затем делегирование на super.getOperation()
, что мне кажется более точным.
class Bar extends Foo {
override def getOperation(t: T): Unit = t match {
case C(i) => println("C")
case _ => super.getOperation(t)
}
}
[*] Предостережение для этого будет сложностью. Существует проблема в версиях Scala до 2.10, в которых средство сопоставления с образцами генерирует слишком сложные файлы .class ( вложенные экстракторы генерируют байт-код экспоненциального пространства ), поэтому, если вы используете совпадение, которое очень сложный, это может вызвать проблемы. Это исправлено в 2.10 с помощью виртуального сопоставителя шаблонов. Если у вас возникла эта проблема, то одним из обходных путей для этой ошибки является разделение совпадений шаблонов на разные методы / классы.