Pregunta

he encontrado que Scala siempre tiene una "explicación natural" a cualquier cosa. Siempre algo así como "ohh, pero eso es sólo una función que se llama en este y que con este objeto y que el parámetro". En un sentido, nada es realmente compilador-mágica como la conocemos de otros idiomas.

Mi pregunta es sobre la <- operador tal como se utiliza en el código siguiente:

for(i <- 0 to 10) println(i)

En este ejemplo se puede ver que está siendo reescrito para algo como:

0.to(10).foreach((i:Int)=>println(i))

pero esto no explica cómo el i se dejó llevar a la función anónima dentro de la función foreach. En el punto en el que escribe i no es un objeto, y sin embargo no es una variable declarada. Entonces, ¿qué es y cómo se está llevando hacia el interior del foreach?

Mi conjetura es que finalmente he descubierto algo que es, de hecho, magia compilador

Gracias por su tiempo.

Para aclarar, mi pregunta es:. ¿Cómo funciona el <- operador de trabajo en la primera línea de código, ya que no es un objeto sobre el que se puede llamar como una función

¿Fue útil?

Solución

<- es un símbolo palabra clave idioma definido, como es => pero en claro contraste con -> (que es un símbolo definido). Debido a que es parte de la gramática básica Scala, que puede ser utilizado para crear enlaces (para el i en su ejemplo), que es algo que no se puede hacer por las construcciones definidas por el usuario.

Otros consejos

Para aumentar la respuesta de Dave, aquí es un esquema de traducción de la 'para-comprensiones' de especificación del lenguaje Scala:

A comprensión for (enums) yield e evalúa la expresión e para cada unión generado por las enumeraciones enumeradores. Una secuencia de empadronador siempre comienza con un generador; Esto puede ser seguido por otros generadores, las definiciones de valor, o dispositivos de seguridad.

A p <- e generador produce fijaciones de un e expresión, que está adaptada de alguna manera contra modelo p. A val p = e valor definición se une la p nombre de valor (o varios nombres en una p patrón) para el resultado de evaluar la e expresión. Un guardia de if e contiene una expresión booleana que restringe fijaciones enumerados.

El significado preciso de los generadores y los guardias se define por la traducción a las invocaciones de cuatro métodos: map, filter, flatMap, y foreach. Estos métodos pueden ser implementados de diferentes maneras para diferentes tipos de portadores.

El esquema de traducción es la siguiente. En un primer paso, cada p <- e generador, en la que p no es irrefutable (§ 8.1) para el tipo de e se sustituye por

 p <- e.filter { case p => true; case _ => false }

A continuación, las siguientes reglas se aplican varias veces hasta que todas las comprensiones han sido eliminado.

  • A para-comprensión for (p <- e) yield e0 se traduce a e.map { case p => e0 }.

  • A para-comprensión for (p <- e) e0 se traduce a e.foreach { case p => e0 }.

  • A para la comprensión-for (p <- e; p0 <- e0 . . .) yield e00, dónde. . . es una (posiblemente vacío) secuencia de generadores o guardias, se traduce a:.
    e.flatMap { case p => for (p0 <- e0 . . .) yield e00 }

  • A para la comprensión-for (p <- e; p0 <- e0 . . .) e00 dónde. . . es una (posiblemente vacía) secuencia de generadores o dispositivos de seguridad, se traduce a:
    e.foreach { case p => for (p0 <- e0 . . .) e00 }.

  • Un generador de p <- e seguido por un guardia de if g se traduce a un único generador:
    p <- e.filter((x1, . . . , xn) => g )
    donde x1,. . . , xn son las variables libres de p.

  • A p <- e generador seguido por una definición val p0 = e0 valor se traduce a la siguiente generador de pares de valores, donde x y x0 son nombres frescas:

    val (p, p0) <- 
      for(x@p <- e) yield { val x0@p0 = e0; (x, x0) }
    

En este caso, lo que realmente es un poco de la magia compilador. La traducción del para-comprensión para filtrar / mapa de formulario / flatmap es un poco especial de desugaring, al igual que la conversión de las formas especiales de actualización y aplicar métodos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top