scala - texto - punto y coma ejemplos
¿Por qué la inferencia de punto y coma de Scala falla aquí? (3)
Comentario adicional a la respuesta por oxbow_lakes ...
var ntests = read nextInt()
Debería arreglar las cosas para usted como una alternativa al punto y coma.
Al compilar el siguiente código con Scala 2.7.3,
package spoj
object Prime1 {
def main(args: Array[String]) {
def isPrime(n: Int) = (n != 1) && (2 to n/2 forall (n % _ != 0))
val read = new java.util.Scanner(System.in)
var nTests = read nextInt // [*]
while(nTests > 0) {
val (start, end) = (read nextInt, read nextInt)
start to end filter(isPrime(_)) foreach println
println
nTests -= 1
}
}
}
Me sale el siguiente error de tiempo de compilación:
PRIME1.scala:8: error: illegal start of simple expression
while(nTests > 0) {
^
PRIME1.scala:14: error: block must end in result expression, not in definition
}
^
two errors found
Cuando agrego un punto y coma al final de la línea comentado como [*]
, el programa se compila bien. ¿Alguien puede explicar por qué la inferencia de punto y coma de Scala no funciona en esa línea en particular?
Es porque scala está asumiendo que está usando la sintaxis a foo b
(equivalente a a.foo(b)
) en su llamada a readInt
. Es decir, asume que el bucle while es el argumento para readInt
(recuerde que cada expresión tiene un tipo) y, por lo tanto, la última declaración es una declaración:
var ntests = read nextInt x
donde x
es tu bloque while.
Debo decir que, como punto de preferencia, ahora he vuelto a usar la a.foo(b)
habitual de a.foo(b)
sobre a foo b
menos que trabaje específicamente con un DSL que fue diseñado con ese uso en mente (como en el de los actores). a ! b
). En general, hace las cosas mucho más claras y no te pican cosas extrañas como esta.
Para agregar un poco más sobre la inferencia de punto y coma, Scala hace esto en dos etapas. Primero, infiere un token especial llamado nl
por la especificación de idioma. El analizador permite que nl
se utilice como separador de instrucciones, así como puntos y coma. Sin embargo, nl
también está permitido en otros lugares por la gramática. En particular, se permite un solo nl
después de los operadores de infijo cuando el primer token en la siguiente línea puede comenzar una expresión, y while
puede comenzar una expresión, es por eso que se interpreta de esa manera. Desafortunadamente, aunque puede comenzar una expresión, una sentencia while no se puede usar en una expresión de infijo, de ahí el error. Personalmente, parece que el analizador es una forma bastante peculiar de trabajar, ¡pero hay una lógica razonable detrás de todo lo que sé!
Como una opción adicional a las otras sugeridas, poner una nueva línea en blanco entre su línea [*]
y la línea de lectura también solucionará el problema, ya que solo se permite un solo nl
después de los operadores de infijo, por lo que múltiples nl
obligan a una interpretación diferente por analizador