Использование операторов сравнения в системе соответствия шаблону Scala

Можно ли сопоставлять сравнение с помощью системы сопоставления шаблонов в Scala? Например:

a match {
    case 10 => println("ten")
    case _ > 10 => println("greater than ten")
    case _ => println("less than ten")
}

Второй аргумент case является незаконным, но я хотел бы указать "когда a больше".

Ответы

Ответ 1

После шаблона вы можете добавить охранник, т.е. if и логическое выражение:

a match {
    case 10 => println("ten")
    case x if x > 10 => println("greater than ten")
    case _ => println("less than ten")
}

Изменить: обратите внимание, что это более чем поверхностно отличается от размещения if после =>, потому что шаблон не будет соответствовать, если защита не соответствует действительности.

Ответ 2

В качестве ответа на вопрос, который задал вопрос о том, как включить предикаты в предложение соответствия, в этом случае предикат можно разделить до match:

def assess(n: Int) {
  println(
    n compare 10 match {
      case 0 => "ten"
      case 1 => "greater than ten"
      case -1 => "less than ten"
    })
}

Теперь документация для scala.math.Ordering.compare(T, T) promises только то, что не равные результаты будут больше или меньше нуля. Java Comparable#compareTo(T) указан аналогично Scala. Обычно принято использовать 1 и -1 для положительного и отрицательного значений соответственно, так как Scala текущая реализация, но можно "сделайте такое предположение без какого-либо риска изменения реализации из-под него.

Ответ 3

Решение, которое, на мой взгляд, намного читаемо, чем добавление охранников:

(n compare 10).signum match {
    case -1 => "less than ten"
    case  0 => "ten"
    case  1 => "greater than ten"
}

Примечания:

  • Ordered.compare возвращает отрицательное целое число, если оно меньше, положительное, если больше, и 0, если он равен.
  • Int.signum сжимает вывод от compare до -1 для отрицательного числа (менее 10), 1 для положительных (более 10), или 0 для нуля (равный 10).

Ответ 4

Использовать защитные устройства:

a match {
    case 10 => println("ten")
    case some if some > 10 => println("greater than ten")
    case _ => println("less than ten")
}