Perché la stringa vuota non corrisponde come Seq.empty?
-
09-09-2019 - |
Domanda
EDIT: Questo era un vecchio bug da tempo fissato in Scala 2.8 e successivamente
Nel corso alcune sperimentazioni attorno domanda corrispondente ad una stringa come Seq [Char] , mi sono imbattuto in un altro fenomeno abbinamento strano. Si consideri il seguente codice che tratta una stringa come una sequenza di caratteri:
def %%&#(input: String) : String = {
val uha : Seq[Char] = input
uha match {
case Seq() => "Empty"
case Seq(first @ _, 'o', 'o') => "Bar"
case _ => "Oh"
}
}
Parlando ingresso sul ""
stringa vuota produce correttamente "Empty"
.
Tuttavia, se riscrivo la prima clausola di corrispondenza come
case Seq.empty => "Empty"
l'incontro tra ""
fallisce e corrisponde alla clausola di default al posto.
A piedi attraverso il codice sorgente della libreria Scala (che non si dovrebbe avere a che fare in un mondo ideale :-)) Credo che sia Seq()
e Seq.empty
si tradurrà in RandomAccessSeq.empty
. Apparentemente, questo non concorda con il fenomeno sopra descritto perché solo Seq()
la stringa vuota.
UPDATE: Su alcuni ulteriori sperimentazioni questa domanda può essere ridotta a quanto segue:
val list = List()
>>> list2: List[Nothing] = List()
val emptySeq = Seq.empty
list == emptySeq
>>> res1: Boolean = false
Ciò significa che un Seq
vuoto non esegue automaticamente uguale Seq.empty
.
Così, quando la corrispondenza con una costante (invece di utilizzare un estrattore come suggerito da starblue) questa disuguaglianza porta alla partita mancanza.
Lo stesso vale per l'interpretazione del String
vuoto come una sequenza.
Soluzione
Questo sembra essere un bug nella libreria. Vuoi depositare il bug o devo?
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
Altri suggerimenti
In corrispondenza delle funzioni unapply o unapplySeq vengono utilizzati, si applica come lei sembra credere.