Сопоставление вложенных и сплющенных образцов в Scala - PullRequest
0 голосов
/ 22 января 2019

Допустим, у меня есть n значений в Scala с именем v 1 , v 2 ,. .., v i , ..., v n типов T ij , которые не обязательно являются разными типами для разных i . Я хочу сопоставить шаблон со значениями n , используя собственную логику.

Один из способов сделать это - вложить все возможности на тот случай, если мне нужно быть исчерпывающим (а для этого примера мне нужно, иначе я мог бы использовать заполнитель mag _ c), и я не могу объединить ветки (что в этом примере не получается, поскольку каждая пользовательская логика уникальна):

v1 match {
  case x1: T11 => v2 match {
    case x2: T21 => v3 match {
      ...
        case xn_1: Tn_11 => vn match {
          case xn: Tn1 => // Custom logic 1.
          case xn: Tn2 => // Custom logic 2.
          ...
          case xn: Tnk => // I am already laughing, but I have to write it down: 
                          // Custom logic k.
        }
        ...     
      ...
    }
    case x2: T22 => v3 match {
      // I guess you get the point. 
    }
    ...
  case x1: T12 => v2 match {
    // And so on until exhaustion in every meaning of the word.
  }
  ... // These three dots are needed here. Now I feel whole.      
}

Другой вариант - выровнять всю чертову вещь:

(v1, v2, ..., vn) match {
    case (x1: T11, x2: T21, ... xn: Tn1) => // Custom logic 1.
    case (x1: T11, x2: T21, ... xn: Tn2) => // Custom logic 1.
    ...
    case (x1: T11, x2: T21, ... xn: Tnk) => // Custom logic k (with a hearthy chuckle).
    ... // Three dots saving my soul and my finger joints.
}

Хотя вложенная версия позволяет избежать дублирования при вводе, она может привести к затруднению чтения кода из-за переполнения отступов, когда значение n высокое (а у нас нет).

С другой стороны, плоская версия содержит много повторяющегося кода, но ее легче интерпретировать.

Кроме того, вложенная версия выглядит более производительной, поскольку проверка x i происходит максимум один раз для каждого типа T ij (но, возможно, мне не стоит беспокоиться о таких вещах, поскольку JVM может просто оптимизировать все это, и я не хочу быть всем злом ).

Какой из них является идиоматическим кодом Scala и поэтому рекомендуется? Есть ли разница в производительности между двумя версиями?

1 Ответ

0 голосов
/ 22 января 2019

Вам следует выбрать вариант, наиболее точно отражающий смысл вашего кода, и не беспокоиться о производительности.Если производительность этого match критична для вашего кода, тогда у вас большие проблемы с вашим дизайном.(Также не ясно, что один работает лучше, чем другой, поэтому выбор, основанный на предполагаемой производительности, был бы неразумным).

Если каждый case приводит к независимому куску кода, то с плоским match является наиболее прямым выражением логики.Добавление ложного вложения просто может привести к путанице.

Если между двумя или более выражениями case существует некоторый общий код, их можно сгруппировать в вложенные операторы match, чтобы общий код не дублировался.Это может также применяться, если есть некоторая логическая общность между несколькими случаями, которые вы хотите выразить в коде.

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

...