web-dev-qa-db-fra.com

Utilisation d'opérateurs de comparaison dans le système de correspondance de modèles de Scala

Est-il possible de faire correspondre une comparaison en utilisant le système de correspondance de modèle dans Scala? Par exemple:

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

La deuxième déclaration de cas est illégale, mais j'aimerais pouvoir spécifier "quand a est supérieur à".

145
BefittingTheorem

Vous pouvez ajouter un garde, c'est-à-dire un if et une expression booléenne après le motif:

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

Edit: Notez que ceci est très superficiellement différent de mettre un ifafter le =>, car un motif non correspond si la valeur de garde n'est pas vraie.

277
Ben James

En tant que non-réponse à l'esprit de la question, qui demandait comment incorporer des prédicats dans une clause de correspondance, dans ce cas, le prédicat peut être factorisé avant le match:

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

Maintenant, la documentation pour scala.math.Ordering.compare(T, T) ne promet que les résultats non égaux seront supérieurs à ou inférieur à zéro . Java Comparable#compareTo(T) est spécifié de la même manière que Scala. Il est courant d'utiliser 1 et -1 pour les valeurs positives et négatives, comme le fait Scala implémentation actuelle , mais on ne peut pas faire une telle hypothèse sans un risque de changement d'implémentation. de dessous.

31
seh

Une solution qui, à mon avis, est beaucoup plus lisible que l’ajout de gardes:

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

Remarques:

  • Ordered.compare renvoie un entier négatif s'il est inférieur, positif si supérieur et 0 si égal.
  • Int.signum compresse la sortie de compare en -1 pour un nombre négatif (inférieur à 10), 1 pour positif (supérieur à 10) ou 0 pour zéro (égal à 10).
17
vergenzt

Alors que toutes les réponses ci-dessus et les réponses ci-dessous répondent parfaitement à la question initiale, des informations supplémentaires sont disponibles dans la documentation https://docs.scala-lang.org/tour/pattern-matching.html , ils ne correspondait pas à mon cas mais parce que cette réponse stackoverflow est la première suggestion de Google, je voudrais poster ma réponse, qui est un exemple de coin de la question ci-dessus.
Ma question est:

  • Comment utiliser une garde dans une expression de correspondance avec un argument d'une fonction?

Qui peut être paraphrasé:

  • Comment utiliser une instruction if dans une expression de correspondance avec un argument de fonction?

La réponse est l'exemple de code ci-dessous:

    def drop[A](l: List[A], n: Int): List[A] = l match {
      case Nil => sys.error("drop on empty list")
      case xs if n <= 0 => xs
      case _ :: xs => drop(xs, n-1)
    }

lien vers scala violon: https://scalafiddle.io/sf/G37THif/2 comme vous pouvez voir le case xs if n <= 0 => xs déclaration est capable d'utiliser n (argument d'une fonction) avec l'instruction guard (if).

J'espère que cela aide quelqu'un comme moi.

1
Sergii Zhuravskyi