花括号和括号之间在Scala中的形式差异是什么,何时使用? [英] What is the formal difference in Scala between braces and parentheses, and when should they be used?

查看:125
本文介绍了花括号和括号之间在Scala中的形式差异是什么,何时使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将参数传递给括号()和花括号 {} 的形式上的区别是什么? / p>

我从 在Scala中编程 书是Scala非常灵活,我应该使用我最喜欢的一种,但是我发现有些情况下可以编译而其他情况下不需要。 p>

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

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

=>错误:简单表达式的非法开头

  val过滤= tupleList.takeWhile {case(s1,s2)=> s1 == s2} 

=>很好。

解决方案

我曾经写过一次,但是由于规则有些分散,我最终还是放弃了。



也许最好集中在花括号和括号可以互换使用的地方:将参数传递给方法时电话。当且仅当该方法需要单个参数时,才可以用大括号替换括号。例如:

  List(1、2、3).reduceLeft {_ + _} //有效的单个Function2 [Int ,Int]参数

List {1、2、3} .reduceLeft(_ + _)//无效,A * vararg参数

但是,您需要了解更多信息才能更好地掌握这些规则。



增加了使用括号的编译检查



Spray的作者建议使用圆括号,因为它们会增加编译检查的次数。这对于Spray等DSL来说尤其重要。通过使用parens,您是在告诉编译器应该只给它一行。因此,如果您不小心给它两个或更多,它会抱怨。大括号现在不是这种情况–例如,如果您忘记了某个位置的运算符,那么您的代码将被编译,并且您会得到意想不到的结果,并且可能会发现很难发现的错误。下面是人为的(因为表达式是纯净的,至少会给出警告),但指出了重点:

 方法{
1 +
2
3
}

方法(
1 +
2
3

第一个编译,第二个给出 error:')'预期,但找到整数文字。作者想写 1 + 2 + 3



一个人可能会说,对于多参数方法,默认参数;



Verbosity



一个经常被忽略的重要提示关于冗长。自 Scala样式指南以来,使用花括号不可避免地导致冗长的代码。 a>明确指出,右花括号必须在自己的行上:


…,右花括号紧随最后一行
函数行。


许多自动重新格式化程序(如IntelliJ)都会自动为您重新格式化。因此,请尽量坚持使用舍入括号。



中缀表示法



在使用中缀表示法时,例如 List(1,2,3)indexOf(2)如果只有一个参数,则可以省略括号并将其写为 List(1、2 ,3)indexOf 2



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



Tuples



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



带有 case


$ b的函数/部分函数文字$ b

Scala具有函数和部分函数文字的语法。看起来像这样:

  {
情况下的模式,如果guard =>语句
案例模式=>语句
}

可以使用的唯一其他地方语句具有 match catch 关键字:

 对象匹配{
case pattern if guard =>语句
案例模式=>语句
}





 尝试{
阻止
}捕获{
案例模式,如果guard =>语句
案例模式=>语句
}最终{

}

您不能在任何其他上下文中使用 case 语句。因此,如果要使用 case ,则需要大括号。如果您想知道是什么导致函数和部分函数文字之间的区别,答案是:上下文。如果Scala需要一个功能,那么您可以获得一个功能。如果期望有部分函数,​​则可以得到部分函数。如果这两者都是预期的,则会产生关于模棱两可的错误。



表达式和块



可以使用括号进行子表达式。花括号可以用来编写代码块(这不是函数文字,所以请当心像使用它一样)。代码块由多个语句组成,每个语句可以是import语句,声明或表达式。它是这样的:

  {
进口东西。_
语句; //;
语句行尾的可选;语句//在这里不是可选的
var x = 0 //声明
而(x< 10){x + = 1} //填充
(x%5)+1 //表达式
}

(表达式)

因此,如果您需要声明,多个语句,导入之类的东西,则需要花括号。并且由于表达式是语句,因此括号可能会出现在花括号内。但是有趣的是,代码块也是也是表达式,因此您可以在表达式的内部中的任何位置使用它们:

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

因此,由于表达式是语句,而代码块是表达式,因此以下所有内容均有效:

  1 //文字
(1)//表达式
{1} //代码块
({1})//表达式一段代码
{(1)} //带有表达式
({(1)})的代码块//您得到了漂移...



在它们不可互换的地方



基本上,您不能替换 {} (),反之亦然。例如:

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

这不是方法调用,因此您不能以任何其他方式编写它。好吧,您可以将花括号 放在条件的括号内,也可以将括号 放在括号内对于代码块:

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

所以,我希望这会有所帮助。


What is the formal difference between passing arguments to functions in parentheses () and in braces {}?

The feeling I got from the Programming in Scala book is that Scala's pretty flexible and I should use the one I like best, but I find that some cases compile while others don't.

For instance (just meant as an example; I would appreciate any response that discusses the general case, not this particular example only):

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

=> error: illegal start of simple expression

val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }

=> fine.

解决方案

I tried once to write about this, but I gave up in the end, as the rules are somewhat diffuse. Basically, you’ll have to get the hang of it.

Perhaps it is best to concentrate on where curly braces and parenthesis can be use interchangeably: when passing parameters to method calls. You may replace parenthesis with curly braces if, and only if, the method expects a single parameter. For example:

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

List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter

However, there’s more you need to know to better grasp these rules.

Increased compile checking with parens

The authors of Spray recommend round parens because they give increased compile checking. This is especially important for DSLs like Spray. By using parens you are telling the compiler that it should only be given a single line; therefore if you accidentally give it two or more, it will complain. Now this isn’t the case with curly braces – if for example you forget an operator somewhere, then your code will compile, and you get unexpected results and potentially a very hard bug to find. Below is contrived (since the expressions are pure and will at least give a warning), but makes the point:

method {
  1 +
  2
  3
}

method(
  1 +
  2
  3
)

The first compiles, the second gives error: ')' expected but integer literal found. The author wanted to write 1 + 2 + 3.

One could argue it’s similar for multi-parameter methods with default arguments; it’s impossible to accidentally forget a comma to separate parameters when using parens.

Verbosity

An important often overlooked note about verbosity. Using curly braces inevitably leads to verbose code since the Scala style guide clearly states that closing curly braces must be on their own line:

… the closing brace is on its own line immediately following the last line of the function.

Many auto-reformatters, like in IntelliJ, will automatically perform this reformatting for you. So try to stick to using round parens when you can.

Infix Notation

When using infix notation, like List(1,2,3) indexOf (2) you can omit parenthesis if there is only one parameter and write it as List(1, 2, 3) indexOf 2. This is not the case of dot-notation.

Note also that when you have a single parameter that is a multi-token expression, like x + 2 or a => a % 2 == 0, you have to use parenthesis to indicate the boundaries of the expression.

Tuples

Because you can omit parenthesis sometimes, sometimes a tuple needs extra parenthesis like in ((1, 2)), and sometimes the outer parenthesis can be omitted, like in (1, 2). This may cause confusion.

Function/Partial Function literals with case

Scala has a syntax for function and partial function literals. It looks like this:

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

The only other places where you can use case statements are with the match and catch keywords:

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

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

You cannot use case statements in any other context. So, if you want to use case, you need curly braces. In case you are wondering what makes the distinction between a function and partial function literal, the answer is: context. If Scala expects a function, a function you get. If it expects a partial function, you get a partial function. If both are expected, it gives an error about ambiguity.

Expressions and Blocks

Parenthesis can be used to make subexpressions. Curly braces can be used to make blocks of code (this is not a function literal, so beware of trying to use it like one). A block of code consists of multiple statements, each of which can be an import statement, a declaration or an expression. It goes like this:

{
    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 )

So, if you need declarations, multiple statements, an import or anything like that, you need curly braces. And because an expression is a statement, parenthesis may appear inside curly braces. But the interesting thing is that blocks of code are also expressions, so you can use them anywhere inside an expression:

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

So, since expressions are statements, and blocks of codes are expressions, everything below is valid:

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...

Where they are not interchangeable

Basically, you can’t replace {} with () or vice versa anywhere else. For example:

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

This is not a method call, so you can’t write it in any other way. Well, you can put curly braces inside the parenthesis for the condition, as well as use parenthesis inside the curly braces for the block of code:

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

So, I hope this helps.

这篇关于花括号和括号之间在Scala中的形式差异是什么,何时使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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