documentación documentacion docs list scala operator-keyword infix-notation cons

list - documentacion - Entendiendo el método infijo llamada y operador de contras(::) en Scala



scala doc (2)

Hay dos cosas de interés aquí: la precedence y la fixity . Como lo mencionó sepp2k, esta pregunta en Stack Overflow explica la precedencia, pensaba que las reglas, tal como se citan, no están lo suficientemente completas, y hubo cambios muy pequeños de Scala 2.7 a Scala 2.8. Sin embargo, las diferencias se refieren principalmente a operadores que terminan en = .

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

Tomemos, pues, este ejemplo:

1 + 2 :: Nil

Primero, la precedencia. ¿Qué tiene más precedencia, + o:? De acuerdo con la tabla, + tiene prioridad sobre : por lo que la adición se realiza primero. Por lo tanto, la expresión es igual a esto:

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

Ahora no hay conflicto de precedencia, pero como :: termina en : tiene una fijación diferente. Se lee de derecha a izquierda, por lo tanto:

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

Por otro lado, en esto:

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 qué punto el error es obvio.

PS: Estoy escribiendo (1).+(2) lugar de 1.+(2) porque, en el momento de escribir esto, 1. se interpreta como un número doble, lo que hace que 1.+(2) una expresión de infijo. agregando el doble 1.0 a 2. Esta sintaxis está en desuso a partir de Scala 2.10.0, y probablemente no estará presente en Scala 2.11.

Soy bastante nuevo en el lenguaje de programación Scala, y estaba probando algo atascado en mi mente mientras seguía las notas de la clase here .

Creo que realmente no pude entender cómo funcionan los operadores contras, aquí hay algunas cosas que probé:

He creado un generador de números pseudoaleatorios y luego he intentado 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 intentó pasar la Lista (3) al método nextnt. Cuando usé paratheses, no hubo problema

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

Tenía curiosidad por el orden de ejecución, así que creé una función para verificarlo

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. Luego pensé que podría tratarse de la función ''nextInt'', luego intenté lo siguiente:

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

Primero ejecutó la suma, y ​​luego se ejecutan los contras. Entonces, aquí está la pregunta: ¿Cuál es la diferencia entre gen nextInt 3 :: Nil y 1 + 2 :: Nil ?


Se trata de la precedencia, no del orden de ejecución. + tiene mayor prioridad que :: , por lo que a + b :: c analiza como (a + b) :: c . Sin embargo, las llamadas al método infijo con nombres regulares tienen una prioridad menor, por lo que a foo bc analiza como a foo (bc) .

Consulte esta pregunta para obtener una lista de operadores ordenados por su prioridad en scala.