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

Как работает | (труба) в работе по сопоставлению с образцом?

Вы можете написать:

str match { case "foo" | "bar" => ... }

На первый взгляд выглядит, что | может быть объектом-экстрактором, однако:

str match { case |("foo", "bar") => ... }

не работает. (И я не вижу, как это может быть реализовано в любом случае.)

Итак, это волшебный встроенный оператор?

(Я считаю, что раньше я видел этот вопрос на SO, но его невозможно было найти...)

4b9b3361

Ответ 1

Да, канал (|) является встроенным для сопоставления с образцом (см. справочную ссылку scala). Раздел соответствия шаблонов (раздел 8) определяет в разделе 8.1.11 так называемые альтернативы шаблонов. В определении говорится:

Альтернатива шаблона p1 |... | рп состоит из ряда альтернатив шаблоны pi. Все альтернативные шаблоны проверяются тип с ожидаемым тип рисунка. Они не могут связываться переменные, отличные от подстановочных знаков. альтернативный шаблон соответствует значению v если хотя бы один из его альтернатив соответствует v.

Итак, да, канал является встроенным, который является контекстом, чувствительным к сопоставлению с образцом.

Ответ 2

| не реализован в библиотеке, он интерпретируется компилятором Scala. Он создает новый шаблон, который определяется как дизъюнкция между двумя подшаблонами, которые не связывают какую-либо переменную (хотя только что сформированный шаблон может быть связан, т.е. Вы можете писать такие вещи, как

try { /*...*/ }
catch {
  case e @ (_: IOException | _: IllegalArgumentException) => /*...*/
}

и e получает как тип наиболее специфичный супертип перечисленных альтернатив).