Pourquoi la chaîne vide correspond pas comme Seq.empty?
-
09-09-2019 - |
Question
EDIT: Ce fut un vieux bug depuis longtemps fixé à Scala 2.8 et plus tard
Au cours de l'expérimentation autour modèle correspondant à une chaîne comme Seq [Char] , je suis tombé sur un autre phénomène correspondant bizarre. Considérons le code suivant qui traite une chaîne de caractères en tant que séquence de caractères:
def %%&#(input: String) : String = {
val uha : Seq[Char] = input
uha match {
case Seq() => "Empty"
case Seq(first @ _, 'o', 'o') => "Bar"
case _ => "Oh"
}
}
Appeler une entrée sur la chaîne vide ""
donne correctement "Empty"
.
Cependant, si je réécris la première clause de match
case Seq.empty => "Empty"
la mise en correspondance de ""
échoue et correspond à la clause par défaut à la place.
Marcher à travers le code source de la bibliothèque Scala (que vous ne devriez pas avoir à faire dans un monde idéal :-) de) Je crois que les deux Seq()
et Seq.empty
entraînera RandomAccessSeq.empty
. Apparemment, cela ne concorde pas avec le phénomène décrit ci-dessus parce que Seq()
correspond à la chaîne vide.
MISE À JOUR: Sur une expérimentation plus loin cette question peut être réduite à ce qui suit:
val list = List()
>>> list2: List[Nothing] = List()
val emptySeq = Seq.empty
list == emptySeq
>>> res1: Boolean = false
Cela signifie essentiellement qu'un Seq
vide ne pas automatiquement égale Seq.empty
.
Ainsi, lorsque la comparaison avec une constante (par opposition à l'aide d'un extracteur comme suggéré par starblue) ce unequality conduit à la rencontre d'échec.
La même chose est vraie pour interpréter la String
vide en tant que séquence.
La solution
Cela semble être un bug dans la bibliothèque. Voulez-vous déposer le bug ou devrais-je?
scala> Seq.empty match {case Seq() => "yup"; case _ => "nope"}
res0: java.lang.String = yup
scala> Seq() match {case Seq.empty => "yup"; case _ => "nope"}
res1: java.lang.String = yup
scala> ("" : Seq[Char]) match {case Seq() => "yup"; case _ => "nope"}
res2: java.lang.String = yup
scala> ("" : Seq[Char]) match {case Seq.empty => "yup"; case _ => "nope"}
res3: java.lang.String = nope
Autres conseils
Dans les fonctions correspondant à unapply ou unapplySeq sont utilisées, pas comme vous semblez appliquer à croire.