2009-04-11 19 views
10

En Scala es posible formular patrones basados ​​en los caracteres invididuales de una cadena tratándola como Seq [Char].Patrón que coincide con una cadena como Seq [Char]

Un ejemplo de esta característica se menciona en A Tour of Scala

Este es el código de ejemplo utilizado allí:

object RegExpTest1 extends Application { 
def containsScala(x: String): Boolean = { 
    val z: Seq[Char] = x 
    z match { 
     case Seq('s','c','a','l','a', rest @ _*) => 
       println("rest is "+rest) 
       true 
     case Seq(_*) => 
       false 
    } 
} 

}

El problema que tengo con esto es la tercera línea del fragmento :

val z: Seq[Char] = x 

¿Por qué es necesario este tipo de molde? ¿No debería una Cadena comportarse como un Seq [Char] bajo todas las circunstancias (que incluiría la coincidencia de patrones)? Sin embargo, sin esta conversión, el fragmento de código no funcionará.

Respuesta

11

No estoy seguro 100% si esto es correcto, pero mi intuición dice que sin este molde explícito que coincida con el patrón java.lang.String, que no es lo que desea.

El lanzamiento explícito fuerza al compilador de Scala a usar la conversión implícita Predef.stringWrapper; por lo tanto, como RichString se extiende Seq[Char], puede hacer una coincidencia de patrón como si la cadena fuera una secuencia de caracteres.

+0

Eso tiene mucho sentido y es básicamente lo que había estado adivinando. Sin embargo, no encontré el convertidor implícito. Gracias por mencionarlo. Básicamente, esta es una gran concesión a la interoperabilidad de Java, sacrificando la solidez de algunos tipos. –

+2

No se pierde la solidez de tipo.La conversión implícita es simplemente el compilador que inserta una llamada a función, algo así como val z: Seq [Char] = string2Seq (x) –

7

Voy a repetir todo lo que dijo andri. Para la interoperabilidad, las cadenas de Scala son java.lang.String s. En Predef, hay una conversión implícita de String a RichString, que implementa Seq[Char].

Una forma quizá más agradable de la codificación de la coincidencia de patrones, sin necesidad de un val intermedia z para mantener el Seq[Char]:

def containsScala(x: String): Boolean = { 
    (x: Seq[Char]) match { 
    ... 
    } 
} 
17

Hay algo de verdadero abuso de la terminología que pasa en la pregunta y los comentarios. No hay ningún molde en este código, y especialmente "Así que, básicamente, esta es una gran concesión a la interoperabilidad de Java, sacrificando la solidez de algunos tipos" no tiene ninguna base en la realidad.

A scala cast se parece a esto: x.asInstanceOf[Y].
Lo que ves arriba es una misión: val z: Seq[Char] = x

Esta asignación es legal porque no hay una conversión implícita String-Seq[Char]. Destaco nuevamente, esto no es un molde. Un yeso es una afirmación arbitraria que puede fallar en el tiempo de ejecución. No hay forma de que la conversión implícita falle.

El problema de depender de las conversiones implícitas entre los tipos, y la respuesta a la pregunta original, es que las conversiones implícitas solo tienen lugar si el valor original no escribe check. Dado que es perfectamente legal hacer coincidir en una cadena, no se realiza ninguna conversión, la coincidencia simplemente falla.

+1

La concesión es que String no puede heredar directamente de Seq [Char] ya que es un typedef al tipo de Java. –

+2

Lo sentimos, tienes razón en que hay una especie de concesión (de hecho, la scala está nadando con ellos), pero no es que haya pérdida de solidez de tipo, lo que significa algo específico y no se ve afectado aquí. – extempore

Cuestiones relacionadas