Pourquoi la correspondance de motifs dans Scala ne fonctionne-t-elle pas avec les variables?

Prendre la fonction suivante:

def fMatch(s: String) = {
    s match {
        case "a" => println("It was a")
        case _ => println("It was something else")
    }
}

Ce modèle correspond bien:

scala> fMatch("a")
It was a

scala> fMatch("b")
It was something else

Ce que je voudrais être en mesure de faire est le suivant:

def mMatch(s: String) = {
    val target: String = "a"
    s match {
        case target => println("It was" + target)
        case _ => println("It was something else")
        }
}

Cela génère l'erreur suivante:

fMatch: (s: String)Unit
<console>:12: error: unreachable code
               case _ => println("It was something else")

Je suppose que c'est parce qu'il pense que target est en fait un nom que vous souhaitez attribuer à quelle que soit l'entrée. Deux questions:

  1. Pourquoi ce comportement? Ne peut pas cas il suffit de chercher des variables existantes dans la portée qui ont le type approprié et les utiliser tout d'abord et, si aucun n'est trouvé, traitez target comme un nom à patternmatch?

  2. Y a-t-il une solution de contournement pour cela? Un moyen de faire correspondre les variables? En fin de Compte, on pourrait utiliser une grande déclaration if, mais le cas de correspondance est plus élégant.

95
demandé sur Henry Henrinson 2011-08-16 16:12:00

1 réponses

Ce que vous cherchez est un identifiant stable. En Scala, ceux-ci doivent soit commencer par une lettre majuscule, soit être entourés de backticks.

Les deux seraient des solutions à votre problème:

def mMatch(s: String) = {
    val target: String = "a"
    s match {
        case `target` => println("It was" + target)
        case _ => println("It was something else")
    }
}

def mMatch2(s: String) = {
    val Target: String = "a"
    s match {
        case Target => println("It was" + Target)
        case _ => println("It was something else")
    }
}

Pour éviter de se référer accidentellement à des variables qui existaient déjà dans la portée englobante, je pense qu'il est logique que le comportement par défaut soit que les modèles en minuscules soient des variables et non des identifiants stables. Seulement quand vous voyez quelque chose commençant par supérieur cas, ou dans les tiques arrière, avez-vous besoin d'être conscient qu'il vient de la portée environnante.

187
répondu Ben James 2011-08-16 12:22:08