Scala中的for( )和for{ }有何不同?

7

我正在尝试理解Scala中的for推导式,我有很多例子,但是我只能大致理解...

有一件事让我很难弄清楚,就是for( ) vs for{ }的区别。我尝试了两种方式,似乎可以在其中一个中实现某些功能,但在另一个中会出错。

例如,这个示例不起作用:

def encode(number: String): Set[List[String]] =
  if (number.isEmpty) Set(List())
  else {
    for (
      split <- 1 to number.length
      word <- wordsForNum(number take split)
      rest <- encode(number drop split)
    ) yield word :: rest
  }.toSet

然而,如果你将它改为{ },它就可以编译:
def encode(number: String): Set[List[String]] =
  if (number.isEmpty) Set(List())
  else {
    for {
      split <- 1 to number.length
      word <- wordsForNum(number take split)
      rest <- encode(number drop split)
    } yield word :: rest
  }.toSet                                 

这些示例来自我正在学习的Coursera课程。教授在视频中没有提到“为什么”,我想知道是否有其他人知道。谢谢!

非常感谢您提供如此详尽的答案 - 我之前没有将需要使用 {} 与我正在处理的多行和单行示例联系起来。 - anonygrits
2个回答

8
从规范中的语法来看,括号和大括号似乎是可以互换的:

http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#for-comprehensions-and-for-loops

但是由于生成器之间使用分号分隔,因此会启用以下规则:

http://www.scala-lang.org/files/archive/spec/2.11/01-lexical-syntax.html#newline-characters

我曾经阅读并理解过这一部分,我依稀记得它的要点是在大括号中启用了新行,也就是说,换行符被视为nl,作为semi

因此,您可以将生成器放在单独的行上,而不是使用分号。

这是通常的“分号推断”,它使您无需编写分号作为语句终止符。例如,在生成器中间的换行符不会被视为分号:

scala> for (c <-
     | List(1,2,3)
     | ) yield c+1
res0: List[Int] = List(2, 3, 4)

scala> for { c <-
     | List(1,2,3)
     | i = c+1
     | } yield i
res1: List[Int] = List(2, 3, 4)

4

在 Scala 中,() 通常用于只有一条语句的情况下。像这样的东西就可以起作用:

def encode(number: String): Set[Int] =
  if (number.isEmpty) Set()
  else {
    for (
      split <- 1 to number.length // Only one statement in the comprehension
    ) split
  }.toSet

添加一个就会无法编译。对于map也是如此。
List(1,2,3).map(number =>
  number.toString
)

不可以(必须使用花括号)

List(1,2,3).map(number =>
  println("Hello world")
  number.toString
)

为什么会这样,我不知道 :)

我之前没有意识到多行代码需要加 {} 。很好的发现。 - WestCoastProjects
1
@javadba 有些人(odersky)总是在多行表达式周围放置大括号,而其他人(paulp)更喜欢在单个跨越多行的表达式周围使用括号。def f = ( if (c) x else y ) - som-snytt
@som-snytt 感谢你的指引。括号和大括号对我来说有些困惑。 - WestCoastProjects

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接