为了账号安全,请及时绑定邮箱和手机立即绑定

大括号和括号在Scala中有什么形式上的区别,应该在什么时候使用它们?

大括号和括号在Scala中有什么形式上的区别,应该在什么时候使用它们?

大括号和括号在Scala中有什么形式上的区别,应该在什么时候使用它们?将参数传递给括号中的函数之间的形式区别是什么?()戴着牙套{}?我从Scala的编程书中说Scala非常灵活,我应该使用我最喜欢的一个,但我发现有些情况是编译的,而另一些则不编译。例如(只是作为一个例子;我希望得到任何讨论一般情况的答复,而不仅仅是这个特定的例子):val tupleList = List[(String, String)]()val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 )=>Error:简单表达式的非法开始val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }=>好。
查看完整描述

3 回答

?
杨魅力

TA贡献1811条经验 获得超6个赞

我试过一次写这篇文章,但最后我放弃了,因为规则有些分散。基本上,你必须掌握它的诀窍。

也许最好集中注意在什么地方可以互换地使用大括号和括号:当将参数传递给方法调用时。你,你们可以,可能将括号替换为大括号当且仅当该方法需要一个参数。例如:

List(1, 2, 3).reduceLeft{_ + _} // valid, single Function2[Int,Int] parameterList{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter

然而,要更好地掌握这些规则,您还需要了解更多的信息。

使用Parens增加编译检查

喷雾的作者推荐圆型父母,因为他们提供更多的编译检查。这对于像喷雾这样的DSL来说尤其重要。通过使用Parens,您正在告诉编译器应该只给它一行;因此,如果您不小心给了它两个或两个以上,它就会抱怨。现在,大括号的情况并非如此-例如,如果您在某个地方忘记了一个操作符,那么您的代码就会编译,您就会得到意想不到的结果,并且可能会有一个很难找到的bug。下面是人为的(因为表达式是纯的,至少会给出一个警告),但是要指出这一点:

method {
  1 +
  2
  3}method(
  1 +
  2
  3)

第一个编译,第二个给出error: ')' expected but integer literal found..作者想写1 + 2 + 3.

对于带有默认参数的多参数方法,人们可能会认为它类似;在使用Parens时,不可能意外地忘记一个逗号来分隔参数。

滔滔不绝

一个经常被忽视的关于冗长的重要注释。使用花括号不可避免地会导致冗长的代码,因为Scala风格指南明确指出,关闭花括号必须在自己的线上:

…关闭大括号紧跟在函数的最后一行之后。

许多自动改革者,如IntelliJ,将自动为您执行此重新格式化。所以当你可以的时候,试着坚持使用圆形的父母。

内定表示法

当使用infix表示法时,如List(1,2,3) indexOf (2)如果只有一个参数,则可以省略括号,并将其写入List(1, 2, 3) indexOf 2..这不是点表示法的情况。

还请注意,当您有一个参数是一个多令牌表达式时,如x + 2a => a % 2 == 0,您必须使用括号来表示表达式的边界。

元组

因为有时可以省略括号,所以元组有时需要额外的括号,如((1, 2)),有时可以省略外括号,如(1, 2)..这可能会造成混乱。

函数/部分函数文字case

Scala有一个函数和部分函数文本的语法。看起来是这样的:

{
    case pattern if guard => statements    case pattern => statements}

唯一一个你可以使用的地方case语句与matchcatch关键词:

object match {
    case pattern if guard => statements    case pattern => statements}
try {
    block} catch {
    case pattern if guard => statements    case pattern => statements} finally {
    block}

你不能用case任何其他上下文中的语句..所以,如果你想用case需要花括号。如果您想知道函数和部分函数文字之间的区别是什么,答案是:Context。如果Scala需要一个函数,则需要一个函数。如果它需要一个部分函数,则得到一个部分函数。如果两者都是预期的,它就会给出一个关于歧义的错误。

表达式和块

括号可用于生成子表达式。大括号可以用来制作代码块(这是一个函数文字,所以要小心尝试像一个函数一样使用它)。代码块由多个语句组成,每个语句都可以是导入语句、声明或表达式。事情是这样的:

{
    import stuff._
    statement ; // ; optional at the end of the line
    statement ; statement // not optional here
    var x = 0 // declaration
    while (x < 10) { x += 1 } // stuff
    (x % 5) + 1 // expression}( expression )

因此,如果需要声明、多个语句,则import或者诸如此类的东西,你需要花括号。由于表达式是语句,括号可能出现在大括号中。但有趣的是,代码块是表达式,因此您可以在任何地方使用它们。表达:

( { var x = 0; while (x < 10) { x += 1}; x } % 5) + 1

因此,由于表达式是语句,代码块是表达式,下面的所有内容都是有效的:

1       // literal(1)     // expression{1}     // block of code({1})   // expression with a block of code{(1)}   // block of code with an expression({(1)}) // you get the drift...

在那里它们是不可互换的

基本上,你不能取代{}带着()反之亦然。例如:

while (x < 10) { x += 1 }

这不是一个方法调用,所以您不能以任何其他方式编写它。你可以把花括号控件的括号。condition,以及使用括号代码块的花括号:

while ({x < 10}) { (x += 1) }

所以我希望这能帮上忙。


查看完整回答
反对 回复 2019-06-28
?
红颜莎娜

TA贡献1842条经验 获得超12个赞

这里有几个不同的规则和推论:首先,Scala在参数是函数时推断大括号,例如list.map(_ * 2)牙套是推断出来的,它只是一种更短的形式list.map({_ * 2})..其次,Scala允许您跳过最后一个参数列表上的括号,如果该参数列表有一个参数,并且它是一个函数,那么list.foldLeft(0)(_ + _)可以写成list.foldLeft(0) { _ + _ }(或list.foldLeft(0)({_ + _})如果你想变得更明确)。

但是,如果添加case正如其他人所提到的,您将得到一个部分函数,而不是一个函数,Scala将不会推断出部分函数的大括号,因此list.map(case x => x * 2)不起作用,但两者都是list.map({case x => 2 * 2})list.map { case x => x * 2 }将要。


查看完整回答
反对 回复 2019-06-28
  • 3 回答
  • 0 关注
  • 1660 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信