Подтвердить что ты не робот

Как соответствие шаблонов в Scala устраняет дублирование, вызванное случаем переключения?

ПРИМЕЧАНИЕ. Я задаю этот вопрос из любознательности и не ставя под сомнение важность языковой функции.

Похоже, это отличная функция, представленная людям из императивного мира программирования. Я новичок в Scala и все еще пытаюсь выяснить, где все, сделайте его массивные множества конструкций подходящими и можно использовать.

Совпадение шаблонов может определенно сделать материал на 100 x лучше, чем в случае с переключателем. но тем не менее, это конструкция случая, над которой мы предпочитаем полиморфизм с момента выхода ООП.

Итак, кратко, что мне трудно понять, это: если случай переключения поощряет дублирование, и мы лучше записываем код, связанный с кодом, в соответствующие классы, то как Scala сопоставление шаблонов преодолевает это?

Мы можем по-прежнему иметь классы или общие классы для различных случаев и снова использовать полиморфизм для нашей потребности.

4b9b3361

Ответ 1

Это вопрос разницы между объектами и структурами данных.

Если вы имеете дело с объектами, используйте политип подтипа - добавление новых типов не требует перекомпиляции, повторного тестирования или перераспределения существующих, тогда как добавление нового алгоритма (метод на интерфейсе, который находится в верхней части иерархия).

Если вы имеете дело с структурами данных, используйте сопоставление patter - добавление новых алгоритмов не требует перекомпиляции, повторного тестирования или перераспределения существующих, тогда как добавление нового типа делает.

Подробнее об этом .

Ответ 2

Согласование Patter - отличная функция, поскольку она проста в использовании.

Он решает проблему "как обеспечить функциональность объектной системы" намного лучше, чем большинство шаблонов проектирования в широко используемых объектно-ориентированных языках. Например, существует шаблон посетителя, который отделяет алгоритм от его структуры объекта. Идея велика, потому что она позволяет нам изменять поведение наших объектов, не затрагивая их классы. Но с другой стороны этот шаблон не справляется с чрезмерной сложностью и многословностью обозначений. При сопоставлении с образцом это можно легко решить:

def calc(e: Expression): Double = e match {
  case Num(n) => n
  case Add(a, b) => calc(a)+calc(b)
  case Sub(a, b) => calc(a)-calc(b)
  ...
}

Это отделяет вычисление AST от его определения и гораздо лучше читается, чем полиморфный шаблон посетителя.

Так как согласование разбиения так просто, мы можем использовать его повсюду - вы найдете его в местах, о которых вы никогда не думали в большинстве языков OO. Отличным примером являются Актеры, которые используют алгебраические типы данных (ADT) для связи между собой:

sealed trait Message
case class Hello(name: String) extends Message
case class Bye(name: String) extends Message
case class Question(q: Symbol) extends Message

class MySelf extends Actor {
  def receive {
    case Hello(name) => println("Hello "+name)
    case Bye(name) => println("Buy "+name)
    case Question('AreYouOk) => sender answer "I'm ok"
    ...
  }
}

Желаю вам много удовольствия, реализовав это с помощью шаблона посетителя!

Ответ 3

Я вижу несколько точек, где соответствие шаблонов завершает ООП и допускает более модульное программирование.

  • Когда у вас есть большой проект, вы хотите избежать "слишком большого поведения" внутри ваших классов домена. Вы можете перемещать поведение снаружи и обычно иметь метод, который получает класс в верхней части иерархии и сопоставляется с дочерними классами.

  • Когда вы используете определенные библиотеки, и вы хотите добавить поведение, но вы не можете изменять источники. Вы также можете использовать неявное преобразование для этого, но в простых случаях сопоставление шаблонов выполняется быстрее и проще.

Чтобы ответить на ваш вопрос, я бы, вероятно, сказал, что вы недооцениваете соответствие шаблону повторного использования кода, которое может принести: когда вы создаете блок соответствия, который создает PartialFunction. Если вам нужно повторно использовать блоки соответствия шаблону, вы можете использовать цепочку PartialFunction, используя метод orElse. Это также приносит пользу при разработке иерархического набора обработчиков определенного объекта, поскольку совпадения выполняются в порядке.

Ответ 4

Конструкции наследования и случая являются действительными способами достижения полиморфизма. Они хороши в несколько разных ситуациях. В отличие от полиморфизма, основанного на наследовании, совпадение шаблонов не является расширяемым, однако часто вам это не нужно. Многие структуры в функциональном программировании, такие как Опция, Либо или::, могут использоваться более кратко с совпадениями с шаблонами, которые описывают полиморфизм и операторы if. В общем, любая проблема может быть решена с помощью любого типа полиморфизма. Это только вопрос элегантности.

Ответ 5

У них действительно нет такой точной проблемы, если вы их оскорбляете.

Точно так же, как полиморфизм по наследству попадает в проблемы, когда он заставляет ваши классы привлекать всевозможные методы, которые на самом деле не относятся к этому классу.

В то время как Java имеет некоторую разумную сильную поддержку наследования, оператор switch просто шутит.

В Scala у вас есть еще более сильная поддержка наследования и удивительное сопоставление шаблонов.

Это ваша работа, чтобы выбрать правильный молоток для ногтя.