在使用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
}
}
}
Run Code Online (Sandbox Code Playgroud)
我得到以下编译时错误:
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
Run Code Online (Sandbox Code Playgroud)
当我在注释为行的末尾添加分号时[*],程序编译正常.任何人都可以解释为什么Scala的分号推断无法在该特定行上工作?
oxb*_*kes 19
是因为scala假设您在调用中使用了语法a foo b(相当于a.foo(b))readInt.也就是说,它假定while循环是参数readInt(回想每个表达式都有一个类型),因此最后一个语句是一个声明:
var ntests = read nextInt x
Run Code Online (Sandbox Code Playgroud)
x你在哪里阻止.
我必须说,作为一个偏好点,我现在已经恢复使用通常的a.foo(b)语法,a foo b 除非特别使用设计时考虑到这种用途的DSL(如演员' a ! b).它让事情变得更加清晰,你不会被这样奇怪的事情所困扰!
小智 11
oxbow_lakes对答案的补充评论......
var ntests = read nextInt()
Run Code Online (Sandbox Code Playgroud)
应该为你解决问题,作为分号的替代品
为了增加关于分号推断的更多信息,Scala实际上分两个阶段进行.首先,它推断出nl语言规范调用的特殊标记.解析器允许nl用作语句分隔符以及分号.但是,nl语法也允许在其他一些地方使用.特别是,nl当下一行的第一个标记可以启动表达式时,在中缀运算符之后允许单个- 并且while可以启动表达式,这就是为什么它以这种方式解释它.不幸的是,虽然while可以启动表达式,但是while语句不能用于中缀表达式,因此错误.就个人而言,解析器工作似乎是一种相当古怪的方式,但对于我知道的所有内容来说,它背后有一个合理的理由!
作为其他人建议的另一种选择,在你的[*]直线和while直线之间放置一个空白换行也将解决问题,因为nl在中缀运算符之后只允许一个,所以多个nls强制解析器进行不同的解释.
| 归档时间: |
|
| 查看次数: |
2611 次 |
| 最近记录: |