2011-08-16 17 views
91

tomar las siguientes funciones:¿Por qué la coincidencia de patrones en Scala no funciona con variables?

def fMatch(s: String) = { 
    s match { 
     case "a" => println("It was a") 
     case _ => println("It was something else") 
    } 
} 

Este patrón coincide muy bien:

scala> fMatch("a") 
It was a 

scala> fMatch("b") 
It was something else 

Lo que me gustaría ser capaz de hacer es la siguiente:

def mMatch(s: String) = { 
    val target: String = "a" 
    s match { 
     case target => println("It was" + target) 
     case _ => println("It was something else") 
     } 
} 

Esto da fuera de la siguiente error:

fMatch: (s: String)Unit 
<console>:12: error: unreachable code 
       case _ => println("It was something else") 

Supongo que esto es porque cree que el objetivo es en realidad un nombre que le gustaría asignar a cualquier entrada. Dos preguntas:

  1. ¿Por qué este comportamiento? ¿No puede el caso simplemente buscar las variables existentes en el alcance que tienen el tipo apropiado y usarlas primero y, si no se encuentran, tratar el destino como un nombre para la coincidencia de patrones?

  2. ¿Hay alguna solución para esto? ¿Hay alguna forma de emparejar patrones con variables? En última instancia, uno podría usar una gran afirmación if, pero el casillero es más elegante.

+0

Relacionados: http://stackoverflow.com/questions/7083502/why-cant-a-variable-be-a-stable-identifier –

+0

Creo que esta pregunta, el código y las respuestas están obsoletos a partir de Scala 2.12.x. Sería bueno si la versión a la que se aplica se menciona como parte de la pregunta. – conny

Respuesta

181

Lo que estás buscando es un identificador estable . En Scala, estos deben comenzar con una letra mayúscula, o estar rodeados por marcadores.

Ambos de estos sería soluciones a su problema:

def mMatch(s: String) = { 
    val target: String = "a" 
    s match { 
     case `target` => println("It was" + target) 
     case _ => println("It was something else") 
    } 
} 

def mMatch2(s: String) = { 
    val Target: String = "a" 
    s match { 
     case Target => println("It was" + Target) 
     case _ => println("It was something else") 
    } 
} 

Para evitar referirse a variables que ya existían en el ámbito de inclusión accidental, creo que tiene sentido que el comportamiento por defecto es que los patrones minúsculas que sean variables e identificadores no estables. Solo cuando veas algo que comienza con mayúsculas o minúsculas, debes ser consciente de que proviene del alcance circundante.

+2

Apuesto a que esto viene de Erlang, donde las variables comienzan con una letra mayúscula y símbolos con minúsculas. –

+9

Observe que 'target' es un valor (' val'), y no una variable ('var'). No funciona con variables. –

+0

Mayúsculas? Tonos de FORTRAN. Débil, Martin, débil. – Malvolio

Cuestiones relacionadas