Использование операторов сравнения в системе соответствия шаблону 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")
}