在scala中什么时候必须使用分号? [英] When is semicolon mandatory in scala?

查看:238
本文介绍了在scala中什么时候必须使用分号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习如何在Scala中编程,并被告知分号在Scala中是可选的.因此,考虑到这一点,我尝试使用以下没有半冒号的嵌套代码块.但是,它在Scala REPL中引发了错误

I am learning how to program in Scala and was being told that semicolon is optional in Scala. So with that in mind, I tried with the following nested block of code which does not have semi colon. However, it throws an error in the Scala REPL

scala> { val a = 1
 | {val b = a * 2
 | {val c = b + 4
 | c}
 | }
 | }
<console>:17: error: Int(1) does not take parameters
   {val b = a * 2

带有半冒号的样本效果很好.

And the sample with semi colon worked perfectly fine.

scala> { val a = 1;
 | { val b = a*2;
 | { val c = b+4; c}
 | }
 | }
res22: Int = 6

因此,在我看来,半冒号并不是真正的可选,在某些情况下是必需的.请问在什么情况下必须使用半冒号?

Therefore it seems to me that semi colon is not really optional and is mandatory in some situations. May I ask in what situation the semi colon is mandatory?

推荐答案

我将尝试从您的示例中提取要点.

I'll try to extract the essence from your example.

请考虑以下代码段:

{ val x = 1 { val y = 2 } }

对于编译器而言,它看起来像

To the compiler, it looks like syntactic sugar for

{ val x = 1.apply({ val y = 2 }) }

但是对象1没有采用块的apply方法,因此编译器会产生错误:

But the object 1 does not have an apply method that takes blocks, therefore the compiler produces an error:

错误:Int(1)不接受参数

error: Int(1) does not take parameters

  { val x = 1 { val y = 2 } }
              ^

对此进行对比

object I { def apply(a: => Any): Unit = () }
{ val x = I { val y = 2 } }

之所以可行,是因为I现在确实具有apply方法.

This works, because I now does have an apply method.

为了使这两种情况之间的区别更加容易一点,在第一种情况下,编译器要求使用分号.

To make the differentiation between these two cases a little bit easier, the compiler requires a semicolon in the first case.

现在人们可能想知道为什么val x = 1{之间的换行符没有转换为推断的分号.我认为规范中的相关报价应为以下内容(

Now one might wonder why a line break between val x = 1 and the { is not converted into an inferred semicolon. I think the relevant quote from the spec would be this (1.2 Newline Characters) (most parts of enumerations omitted ([...]), emphasis mine):

Scala语法包含以下形式的产生式: 接受可选的nl令牌,但不接受分号.这有 表示其中一个位置的换行符不会终止 表达式或语句.这些职位可以总结如下:

The Scala grammar [...] contains productions where optional nl tokens, but not semicolons, are accepted. This has the effect that a newline in one of these positions does not terminate an expression or statement. These positions can be summarized as follows:

[...]

  • 在大括号之前"{",如果该大括号是当前语句或表达式的合法延续

[...]

请注意,此报价仅涵盖带有可选换行符的情况.它不适用于两个或多个连续的换行符,例如

Note that this quote covers only the case with a single optional line break. It does not hold for two or more consecutive line breaks, e.g.

scala> {
     |   val x = 1
     | 
     |   { val y = 2 }
     | }

有效,并且{ val y = 2 }被解析为单独的表达式.

is valid, and { val y = 2 } is parsed as a separate expression.

猜测的动机是允许嵌入式DSL带有如下语法糖:

I guess the motivation was to allow embedded DSL's with syntactic sugar like this:

MY_WHILE(x >= 0)
{
  println(x)
  x -= 1
}

如果必须将每个这样的MY_WHILE陈述都放入另一对圆括号中,这真的很奇怪,不是吗?

It would be really strange if one had to enclose each such MY_WHILE-statement into an additional pair of round parentheses, wouldn't it?

这篇关于在scala中什么时候必须使用分号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆