gpt4 book ai didi

scala - 花括号和括号之间在Scala中的形式差异是什么?何时使用?

转载 作者:行者123 更新时间:2023-12-01 15:00:11 25 4
gpt4 key购买 nike

将参数传递给括号()和括号{}中的函数有什么形式上的区别?

我从Programming in Scala书中得到的感觉是Scala非常灵活,我应该使用我最喜欢的那种,但是我发现有些情况下可以编译,而有些情况下则不需要。

例如(仅作为示例;我不胜感激任何讨论一般情况的回复,而不仅限于此特定示例):

val tupleList = List[(String, String)]()
val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 )

=>错误:简单表达式的非法启动
val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }

=>很好。

最佳答案

我曾经尝试写过一次,但是由于规则有些分散,最终我还是放弃了。基本上,您必须掌握它。
也许最好集中在大括号和括号可以互换使用的地方:将参数传递给方法调用时。仅在该方法需要单个参数的情况下,才可以用花括号替换括号。例如:

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

List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter
但是,您需要了解更多信息才能更好地掌握这些规则。
使用parens增加了编译检查
Spray的作者建议使用圆括号,因为它们可以提高编译检查的效率。这对于Spray等DSL来说尤其重要。通过使用parens,您是在告诉编译器应该只给它一行。因此,如果您不小心给它两个或更多,它会抱怨。大括号现在不是这种情况–例如,如果您忘记了某个位置的运算符,那么您的代码将被编译,并且您会得到意想不到的结果,并且可能会发现很难发现的错误。下面是人为设计的(因为表达式是纯净的,至少会给出警告),但指出了这一点:
method {
1 +
2
3
}

method(
1 +
2
3
)
第一个编译,第二个给出 error: ')' expected but integer literal found。作者想写 1 + 2 + 3
有人可能会说它与带有默认参数的多参数方法相似;使用parens时,会偶然忘记逗号分隔参数的可能性。
细度
关于冗长性的一个经常被忽视的重要提示。使用花括号不可避免地会导致冗长的代码,因为 Scala style guide明确指出,右花括号必须位于其自己的行上:

…最后一个括号紧跟在最后一行
函数行。

像IntelliJ中一样,许多自动重新格式化程序将自动为您重新格式化。因此,请尽量使用圆形括号。
中缀符号
当使用像 List(1,2,3) indexOf (2)这样的中缀表示法时,如果只有一个参数,则可以省略括号并将其写为 List(1, 2, 3) indexOf 2。这不是点符号的情况。
还要注意,当您有一个作为多 token 表达式的单个参数(例如 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,则需要花括号。如果您想知道是什么导致函数和部分函数文字之间的区别,答案是:上下文。如果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) }
因此,我希望这会有所帮助。

关于scala - 花括号和括号之间在Scala中的形式差异是什么?何时使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51162270/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com