2009-04-11 3 views
2

EDIT: Dies war ein alter Bug in Scala fixiert längst 2.8 und späterWarum stimmt die leere Zeichenfolge nicht als Seq.empty überein?

Während einigen Experimenten um Frage Pattern matching a String as Seq[Char] ich über eine andere seltsame Matching Phänomen lief. Betrachten Sie den folgenden Code, der eine Zeichenfolge als eine Folge von Zeichen behandelt:

def %%&#(input: String) : String = { 
    val uha : Seq[Char] = input 
    uha match { 
     case Seq() => "Empty" 
     case Seq(first @ _, 'o', 'o') => "Bar" 
     case _ => "Oh" 
    } 
} 

Aufruf Eingang auf dem leeren String "" richtig "Empty" ergibt.

Allerdings, wenn ich das erste Spiel Klausel als

case Seq.empty => "Empty" 

die Anpassung der "" ausfällt und entspricht dem Standard-Klausel anstatt neu zu schreiben.

Durch den Quellcode der Scala-Bibliothek gehen (was Sie in einer idealen Welt nicht tun sollten :-)) Ich glaube, dass sowohl Seq() als auch Seq.empty zu RandomAccessSeq.empty führen werden. Offensichtlich stimmt dies nicht mit dem oben beschriebenen Phänomen überein, da nur Seq() mit dem leeren String übereinstimmt.

UPDATE: Nach einigen weiteren Experimenten kann diese Frage bis auf die folgenden verengt werden:

val list = List() 
    >>> list2: List[Nothing] = List() 
val emptySeq = Seq.empty 
list == emptySeq 
    >>> res1: Boolean = false 

Das bedeutet im Wesentlichen, dass ein leerer Seq nicht automatisch gleich Seq.empty. Beim Vergleich mit einer Konstanten (im Gegensatz zur Verwendung eines Extraktors wie von Sternenblau vorgeschlagen) führt diese Ungleichheit zu einer fehlerhaften Übereinstimmung. Das gleiche gilt, wenn die leere String als Sequenz interpretiert wird.

+1

Offenbar wird dies in Scala 2.8 gelöst werden. Sich auf etwas freuen. –

+0

Gut, aber jetzt abgelaufen, seit der Fehler behoben ist (vielleicht schon vor Jahren). Was ist die Stackoverflow-Richtlinie, um diese in Ruhe zu setzen, damit sie bei Suchvorgängen nicht angezeigt wird? – akauppi

+0

Könntest du bitte irgendwie anmerken, dass dies nur für Scala <2.8 gilt (es steht im Kommentar aber wir fangen nicht an dort zu lesen). Meta hat eine offene Diskussion darüber, was mit Problemen zu tun ist. dies: http://meta.stackoverflow.com/questions/252520/mark-questions-oranswers-as-out-of-date – akauppi

Antwort

4

Dies scheint ein Fehler in der Bibliothek zu sein. Willst du den Fehler ablegen oder soll ich?

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 
+0

Also der Fehler ist wirklich, dass viele Subtypen von Seq [A] wie List und RichString sind nicht gleich Seq.empty, wenn sie konstruiert sind (mit List() bzw. ("": Seq [Char])), während andere wie RandomAccessSeq sind. Könnte das aus irgendeinem Grund beabsichtigt sein? –

0

In Übereinstimmung mit den unapply oder unapplySeq Funktionen verwendet werden, nicht so, wie Sie glauben scheinen.

Verwandte Themen