2011-10-25 9 views
7

Como seguimiento a this preguntaRegex y la coincidencia de patrón en la Parte II Scala

Aquí hay un código que compila y se ejecuta correctamente, utilizando las capturas.

val myString = "ACATCGTAGCTGCTAGCTG" 

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

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

>scala scalaTest.scala 
dna:ACATCGTAGCTGCTAGCTG 

Aquí hay un código más simple, sin captura, que no se compila.

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 

Parece que la coincidencia debe devolver un valor booleano independientemente de si se utiliza una captura. ¿Qué está pasando aquí?

Respuesta

8

En su bloque match, nuc es una variable de patrón y no se refiere al nuc en el alcance adjunto. Esto hace que el caso predeterminado sea inalcanzable porque el patrón simple nuc coincidirá con cualquier cosa.

Un par de paréntesis vacío en nuc hará que el trabajo de azúcar sintáctica y llamar al método unapplySeq en la expresión regular:

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

Una forma de evitar este escollo es renombrar nuc a Nuc. Comenzar con una letra mayúscula lo convierte en un identificador estable, por lo que se refiere al Nuc en el ámbito adjunto, en lugar de ser tratado por el compilador como una variable de patrón.

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

Lo anterior imprimirá "not dna", porque aquí estamos simplemente comparando Nuc-myString, y ellos no son iguales. Es un error, ¡pero tal vez menos confuso!

Adición de los paréntesis, tendrá el efecto deseado también en este caso:

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

Por cierto, no es un valor booleano que está siendo devuelta, pero 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

para no criticar, pero ¿por qué dice que el caso predeterminado es inalcanzable (caso _ => println ("not dna")) –

+0

Me perdí eso en mi respuesta, lo actualicé ahora para explicar eso. –

Cuestiones relacionadas