Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
大括号和圆括号在Scala中的形式差异是什么,何时使用它们?_Scala_Syntax_Parentheses_Braces - Fatal编程技术网

大括号和圆括号在Scala中的形式差异是什么,何时使用它们?

大括号和圆括号在Scala中的形式差异是什么,何时使用它们?,scala,syntax,parentheses,braces,Scala,Syntax,Parentheses,Braces,在括号()和大括号{}中向函数传递参数的形式上有什么区别 我从这本书中得到的感觉是Scala非常灵活,我应该使用我最喜欢的一个,但我发现有些案例可以编译,而其他的则不能 例如(只是作为一个示例;我希望任何讨论一般情况的回复,而不仅仅是这个特定示例): =>错误:简单表达式的开始非法 val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 } =>很好。因为您使用的是case,所以您定义的是部分函数,部分函数需要大括号。社

在括号
()
和大括号
{}
中向函数传递参数的形式上有什么区别

我从这本书中得到的感觉是Scala非常灵活,我应该使用我最喜欢的一个,但我发现有些案例可以编译,而其他的则不能

例如(只是作为一个示例;我希望任何讨论一般情况的回复,而不仅仅是这个特定示例):

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

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

=>很好。

因为您使用的是
case
,所以您定义的是部分函数,部分函数需要大括号。

社区正在努力使大括号和圆括号的使用标准化,请参阅Scala Style Guide(第21页):

高阶方法调用的推荐语法是始终使用大括号,并跳过点:

val filtered = tupleList takeWhile { case (s1, s2) => s1 == s2 }
对于“正常”metod调用,应使用点和括号

val result = myInstance.foo(5, "Hello")

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


但是,如果您添加
case
,您会得到一个分部函数,而不是一个函数,Scala不会为分部函数推断大括号,因此
list.map(case x=>x*2)
不起作用,但
list.map({case x=>2*2})
list.map{case x=>x*2}
will.

我曾经试着写过这篇文章,但最终还是放弃了,因为规则有些分散。基本上,你必须掌握窍门

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

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

List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter
while (x < 10) { x += 1 }
然而,为了更好地掌握这些规则,您还需要知道更多

使用parens增加编译检查 Spray的作者推荐round Paren,因为它们增加了编译检查。这对于像Spray这样的DSL尤其重要。通过使用parens,你告诉编译器应该只给它一行;因此,如果你不小心给它两个或更多,它会抱怨。现在大括号不是这种情况——例如,如果您忘记了某个操作符,那么您的代码将被编译,您将得到意外的结果,并且可能很难找到一个bug。下面是精心设计的(因为这些表达是纯粹的,至少会给出一个警告),但强调了这一点:

method {
  1 +
  2
  3
}

method(
  1 +
  2
  3
)
第一个编译,第二个给出预期的
错误:')'但找到整数文本
。作者想写
1+2+3

有人可能会说,对于带有默认参数的多参数方法,情况类似;在使用参数时,不可能意外地忘记用逗号分隔参数

冗长 一个重要的,经常被忽略的关于冗长的注释。使用大括号不可避免地会导致冗长的代码,因为清楚地说明结束大括号必须在其自己的行上:

…右大括号紧跟在最后一行之后 函数的行

许多自动重新格式化程序(如IntelliJ)将自动为您执行此重新格式化。所以,尽可能地坚持使用圆括号

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

还请注意,如果有一个参数是多标记表达式,如
x+2
a=>a%2==0
,则必须使用括号来指示表达式的边界

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

带有
大小写的函数/部分函数文字
Scala具有函数和部分函数文本的语法。看起来是这样的:

{
    case pattern if guard => statements
    case pattern => statements
}
{
    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 )
您可以使用
case
语句的唯一其他位置是
match
catch
关键字:

object match {
    case pattern if guard => statements
    case pattern => statements
}
不能在任何其他上下文中使用
case
语句。因此,如果要使用
大小写
,则需要大括号。如果您想知道函数和部分函数文字之间的区别,答案是:上下文。如果Scala需要一个函数,那么您将得到一个函数。如果它需要一个分部函数,则得到一个分部函数。如果两者都是预期的,则会给出一个关于歧义的错误

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

{
    case pattern if guard => statements
    case pattern => statements
}
{
    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 )
因此,因为表达式是语句,代码块是表达式,所以下面的所有内容都是有效的:

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...
它们不能互换的地方 基本上,你不能用
()
替换
{}
,反之亦然。例如:

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

List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter
while (x < 10) { x += 1 }

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

我认为这是值得解释的
2 + { 3 }             // res: Int = 5
val x = { 4 }         // res: x: Int = 4
List({1},{2},{3})     // res: List[Int] = List(1,2,3)
def foo(f: Int => Unit) = { println("Entering foo"); f(4) }
foo( x => println(x) )
foo({ x => println(x) })
foo({ println("Hey"); x => println(x) })
foo { println("Hey"); x => println(x) }
foo { x => println(x) }
val tupleList = List[(String, String)]()
// doesn't compile, violates case clause requirement
val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 ) 
// block of code as a partial function and parentheses omission,
// i.e. tupleList.takeWhile({ case (s1, s2) => s1 == s2 })
val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }

// curly braces omission, i.e. List(1, 2, 3).reduceLeft({_+_})
List(1, 2, 3).reduceLeft(_+_)
// parentheses omission, i.e. List(1, 2, 3).reduceLeft({_+_})
List(1, 2, 3).reduceLeft{_+_}
// not both though it compiles, because meaning totally changes due to precedence
List(1, 2, 3).reduceLeft _+_ // res1: String => String = <function1>

// curly braces omission, i.e. List(1, 2, 3).foldLeft(0)({_ + _})
List(1, 2, 3).foldLeft(0)(_ + _)
// parentheses omission, i.e. List(1, 2, 3).foldLeft(0)({_ + _})
List(1, 2, 3).foldLeft(0){_ + _}
// block of code and parentheses omission
List(1, 2, 3).foldLeft {0} {_ + _}
// not both though it compiles, because meaning totally changes due to precedence
List(1, 2, 3).foldLeft(0) _ + _
// error: ';' expected but integer literal found.
List(1, 2, 3).foldLeft 0 (_ + _)

def foo(f: Int => Unit) = { println("Entering foo"); f(4) }
// block of code that just evaluates to a value of a function, and parentheses omission
// i.e. foo({ println("Hey"); x => println(x) })
foo { println("Hey"); x => println(x) }

// parentheses omission, i.e. f({x})
def f(x: Int): Int = f {x}
// error: missing arguments for method f
def f(x: Int): Int = f x
method {
  1 +
  2
  3
}

method(
  1 +
  2
  3
 )
List(1, 2, 3).reduceLeft {
  _ + _
}