2011-10-25 21 views
7

Come follow-up a this domandaRegex e Pattern Matching a Scala Parte II

Ecco alcuni codice che viene compilato ed eseguito in modo corretto, con catture.

val myString = "ACATCGTAGCTGCTAGCTG" 

val nucCap = "([ACTG]+)".r 

myString match { 
    case nucCap(myNuc) => println("dna:"+myNuc) 
    case _ => println("not dna") 
} 

>scala scalaTest.scala 
dna:ACATCGTAGCTGCTAGCTG 

Ecco un codice più semplice, senza acquisizione, che non viene compilato.

val myString = "ACATCGTAGCTGCTAGCTG" 

val nuc = "[ACGT]+".r 

myString match { 
    case nuc => println("dna") 
    case _ => println("not dna") 
} 

>scala scalaTest.scala 
scalaTest.scala:7: error: unreachable code 

Sembra che la corrispondenza debba restituire un valore booleano indipendentemente dal fatto che venga utilizzata un'acquisizione. Cosa sta succedendo qui?

risposta

8

Nel blocco match, nuc è una variabile di modello e non fa riferimento allo nuc nell'ambito di inclusione. Questo rende il caso predefinito irraggiungibile perché il modello semplice nuc corrisponderà a qualsiasi cosa.

Una coppia di parentesi vuote sulla nuc renderà il lavoro zucchero sintattico e chiamare il metodo unapplySeq sulla Regex:

myString match { 
    case nuc() => println("dna") 
    case _ => println("not dna") 
} 

Un modo per evitare questa trappola è rinominare nuc a Nuc. A partire da una lettera maiuscola diventa un identificatore stabile, quindi fa riferimento allo Nuc nell'ambito di inclusione, anziché essere trattato dal compilatore come variabile di modello.

val Nuc = "[ACGT]+".r 
myString match { 
    case Nuc => println("dna") 
    case _ => println("not dna") 
} 

È possibile che questo stamperà "not dna", perché qui stiamo semplicemente confrontando Nuc-myString, e loro non sono uguali. È un bug, ma forse uno meno confusionario!

Aggiungendo le parentesi avrà l'effetto desiderato in questo caso:

myString match { 
    case Nuc() => println("dna") 
    case _ => println("not dna") 
} 
// prints "dna" 

proposito, non è un booleano che viene restituito, ma un Option[List[String]]:

scala> nuc.unapplySeq(myString) 
res17: Option[List[String]] = Some(List()) 
scala> nucCap.unapplySeq(myString) 
res18: Option[List[String]] = Some(List(ACATCGTAGCTGCTAGCTG)) 
+0

non fare il pasticcio ma perché dice che il caso predefinito è irraggiungibile (caso _ => println ("not dna")) –

+0

Mi mancava quello nella mia risposta - lo aggiorna ora per spiegarlo. –