Pregunta

Soy bastante nuevo en lenguaje de programación Scala, y estaba intentando algo stucked en mi mente mientras yo estaba siguiendo las notas de la conferencia a aquí .

Creo que realmente no podía entender cómo funciona contras operador, aquí hay algunas cosas que intenté:

He creado un generador de números pseudo-aleatorios, luego trató de crear una lista de un valor aleatorio:

scala> val gen = new java.util.Random
gen: java.util.Random = java.util.Random@1b27332

scala> gen nextInt 3 :: Nil
<console>:7: error: type mismatch;
 found   : List[Int]
 required: Int
       gen nextInt 3 :: Nil
                     ^

Pero trató de pasar lista (3) con el método nextnt. Cuando solía paratheses, no había ningún problema

scala> (gen nextInt 3) :: Nil
res69: List[Int] = List(1)

Yo tenía curiosidad acerca de la orden de ejecución, así que creé una función para comprobarlo

scala> def pr(i:Int):Int = { println(i); i }
pr: (i: Int)Int

scala> pr(1) :: pr(2) :: pr(3) :: Nil
1
2
3
res71: List[Int] = List(1, 2, 3)

Como se ve en las salidas, el orden de ejecución es el mismo que el orden de aparición. Entonces pensé que podría ser sobre la función 'nextInt', entonces intenté siguiente:

scala> 1 + 2 :: Nil
res72: List[Int] = List(3)

Además primero ejecutada, y después de que los contras se ejecuta. Así que aquí está la pregunta: ¿Cuál es la diferencia entre gen nextInt 3 :: Nil y 1 + 2 :: Nil

¿Fue útil?

Solución

Hay dos cosas de interés aquí: precedencia y fijeza . Como se mencionó sepp2k, esta pregunta desbordamiento de pila explica la precedencia, que se cree las reglas, como se cita, no son lo suficientemente completa, y no hubo cambios muy pequeños de Scala Scala 2,7 a 2,8. Las diferencias se refieren en su mayoría operadores que terminan en =, sin embargo.

fijeza , casi todo en Scala se lee de izquierda a derecha, que es lo que los programadores están acostumbrados. En Scala, sin embargo, los operadores que terminan en : se leen de derecha a izquierda.

Toma, pues, este ejemplo:

1 + 2 :: Nil

En primer lugar, la precedencia. Lo que tiene más precedencia, + o :? De acuerdo con la tabla, + tiene prioridad sobre :, por lo que la adición se realiza en primer lugar. Por lo tanto, la expresión es igual a este:

((1).+(2)) :: Nil

Ahora no hay conflicto precedencia, pero desde extremos :: en :, que tiene una fijeza diferent. Es derecho de lectura a la izquierda, por lo tanto:

Nil.::((1).+(2))

Por otro lado, en este:

gen nextInt 3 :: Nil

El :: operador tiene prioridad sobre nextInt, porque : tiene prioridad sobre todas las letras. Por lo tanto, y recordando su fijeza, se convierte en:

gen nextInt Nil.::(3)

que luego se convierte

gen.nextInt(Nil.::(3))

en cuyo punto el error es evidente.

PS: Estoy escribiendo (1).+(2) en lugar de 1.+(2) porque, en el momento de escribir estas líneas, 1. se interpreta como un número doble, haciendo 1.+(2) una expresión infija añadiendo el doble de 1,0 a 2. Esta sintaxis está obsoleta de Scala 2.10 0.0, y probablemente no estar presente en Scala 2.11.

Otros consejos

Se trata de no preferencia orden de ejecución. + tiene mayor precedencia que ::, así como análisis sintácticos a + b :: c (a + b) :: c. Sin embargo las llamadas a métodos infijas con nombres regulares tienen prioridad más baja, por lo a foo b c análisis sintácticos como a foo (b c).

esta pregunta para obtener una lista de los operadores ordenado por su precedencia en Scala.

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