猿问

大括号和括号在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 }

=>好。


呼啦一阵风
浏览 1661回答 3
3回答

杨魅力

我试过一次写这篇文章,但最后我放弃了,因为规则有些分散。基本上,你必须掌握它的诀窍。也许最好集中注意在什么地方可以互换地使用大括号和括号:当将参数传递给方法调用时。你,你们可以,可能将括号替换为大括号当且仅当该方法需要一个参数。例如:List(1,&nbsp;2,&nbsp;3).reduceLeft{_&nbsp;+&nbsp;_}&nbsp;//&nbsp;valid,&nbsp;single&nbsp;Function2[Int,Int]&nbsp;parameterList{1,&nbsp;2,&nbsp;3}.reduceLeft(_&nbsp;+&nbsp;_)&nbsp;//&nbsp;invalid,&nbsp;A*&nbsp;vararg&nbsp;parameter然而,要更好地掌握这些规则,您还需要了解更多的信息。使用Parens增加编译检查喷雾的作者推荐圆型父母,因为他们提供更多的编译检查。这对于像喷雾这样的DSL来说尤其重要。通过使用Parens,您正在告诉编译器应该只给它一行;因此,如果您不小心给了它两个或两个以上,它就会抱怨。现在,大括号的情况并非如此-例如,如果您在某个地方忘记了一个操作符,那么您的代码就会编译,您就会得到意想不到的结果,并且可能会有一个很难找到的bug。下面是人为的(因为表达式是纯的,至少会给出一个警告),但是要指出这一点:method&nbsp;{ &nbsp;&nbsp;1&nbsp;+ &nbsp;&nbsp;2 &nbsp;&nbsp;3}method( &nbsp;&nbsp;1&nbsp;+ &nbsp;&nbsp;2 &nbsp;&nbsp;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 + 2或a => a % 2 == 0,您必须使用括号来表示表达式的边界。元组因为有时可以省略括号,所以元组有时需要额外的括号,如((1, 2)),有时可以省略外括号,如(1, 2)..这可能会造成混乱。函数/部分函数文字caseScala有一个函数和部分函数文本的语法。看起来是这样的:{ &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;pattern&nbsp;if&nbsp;guard&nbsp;=>&nbsp;statements&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;pattern&nbsp;=>&nbsp;statements}唯一一个你可以使用的地方case语句与match和catch关键词:object&nbsp;match&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;pattern&nbsp;if&nbsp;guard&nbsp;=>&nbsp;statements&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;pattern&nbsp;=>&nbsp;statements}try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;block}&nbsp;catch&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;pattern&nbsp;if&nbsp;guard&nbsp;=>&nbsp;statements&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;pattern&nbsp;=>&nbsp;statements}&nbsp;finally&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;block}你不能用case任何其他上下文中的语句..所以,如果你想用case你需要花括号。如果您想知道函数和部分函数文字之间的区别是什么,答案是:Context。如果Scala需要一个函数,则需要一个函数。如果它需要一个部分函数,则得到一个部分函数。如果两者都是预期的,它就会给出一个关于歧义的错误。表达式和块括号可用于生成子表达式。大括号可以用来制作代码块(这是不一个函数文字,所以要小心尝试像一个函数一样使用它)。代码块由多个语句组成,每个语句都可以是导入语句、声明或表达式。事情是这样的:{ &nbsp;&nbsp;&nbsp;&nbsp;import&nbsp;stuff._ &nbsp;&nbsp;&nbsp;&nbsp;statement&nbsp;;&nbsp;//&nbsp;;&nbsp;optional&nbsp;at&nbsp;the&nbsp;end&nbsp;of&nbsp;the&nbsp;line &nbsp;&nbsp;&nbsp;&nbsp;statement&nbsp;;&nbsp;statement&nbsp;//&nbsp;not&nbsp;optional&nbsp;here &nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;x&nbsp;=&nbsp;0&nbsp;//&nbsp;declaration &nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(x&nbsp;<&nbsp;10)&nbsp;{&nbsp;x&nbsp;+=&nbsp;1&nbsp;}&nbsp;//&nbsp;stuff &nbsp;&nbsp;&nbsp;&nbsp;(x&nbsp;%&nbsp;5)&nbsp;+&nbsp;1&nbsp;//&nbsp;expression}(&nbsp;expression&nbsp;)因此,如果需要声明、多个语句,则import或者诸如此类的东西,你需要花括号。由于表达式是语句,括号可能出现在大括号中。但有趣的是,代码块是也表达式,因此您可以在任何地方使用它们。内表达:(&nbsp;{&nbsp;var&nbsp;x&nbsp;=&nbsp;0;&nbsp;while&nbsp;(x&nbsp;<&nbsp;10)&nbsp;{&nbsp;x&nbsp;+=&nbsp;1};&nbsp;x&nbsp;}&nbsp;%&nbsp;5)&nbsp;+&nbsp;1因此,由于表达式是语句,代码块是表达式,下面的所有内容都是有效的:1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;literal(1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;expression{1}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;block&nbsp;of&nbsp;code({1})&nbsp;&nbsp;&nbsp;//&nbsp;expression&nbsp;with&nbsp;a&nbsp;block&nbsp;of&nbsp;code{(1)}&nbsp;&nbsp;&nbsp;//&nbsp;block&nbsp;of&nbsp;code&nbsp;with&nbsp;an&nbsp;expression({(1)})&nbsp;//&nbsp;you&nbsp;get&nbsp;the&nbsp;drift...在那里它们是不可互换的基本上,你不能取代{}带着()反之亦然。例如:while&nbsp;(x&nbsp;<&nbsp;10)&nbsp;{&nbsp;x&nbsp;+=&nbsp;1&nbsp;}这不是一个方法调用,所以您不能以任何其他方式编写它。你可以把花括号内控件的括号。condition,以及使用括号内代码块的花括号:while&nbsp;({x&nbsp;<&nbsp;10})&nbsp;{&nbsp;(x&nbsp;+=&nbsp;1)&nbsp;}所以我希望这能帮上忙。

红颜莎娜

这里有几个不同的规则和推论:首先,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 }将要。
随时随地看视频慕课网APP
我要回答