On compiling the following code with 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
}
}
}
I get the following compile time error :
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
When I add a semicolon at the end of the line commented as [*]
, the program compiles fine. Can anyone please explain why does S开发者_如何学编程cala's semicolon inference fail to work on that particular line?
Is it because scala is assuming that you are using the syntax a foo b
(equivalent to a.foo(b)
) in your call to readInt
. That is, it assumes that the while
loop is the argument to readInt
(recall that every expression has a type) and hence the last statement is a declaration:
var ntests = read nextInt x
wherex
is your while block.
I must say that, as a point of preference, I've now returned to using the usual a.foo(b)
syntax over a foo b
unless specifically working with a DSL which was designed with that use in mind (like actors' a ! b
). It makes things much clearer in general and you don't get bitten by weird stuff like this!
Additional comment to the answer by oxbow_lakes...
var ntests = read nextInt()
Should fix things for you as an alternative to the semicolon
To add a little more about the semicolon inference, Scala actually does this in two stages. First it infers a special token called nl
by the language spec. The parser allows nl
to be used as a statement separator, as well as semicolons. However, nl
is also permitted in a few other places by the grammar. In particular, a single nl
is allowed after infix operators when the first token on the next line can start an expression -- and while
can start an expression, which is why it interprets it that way. Unfortunately, although while
can start a expression, a while statement cannot be used in an infix expression, hence the error. Personally, it seems a rather quirky way for the parser to work, but there's quite plausibly a sane rationale behind it for all I know!
As yet another option to the others suggested, putting a blank newline between your [*]
line and the while
line will also fix the problem, because only a single nl
is permitted after infix operators, so multiple nl
s forces a different interpretation by the parser.
精彩评论