我正在尝试学习 scala,并试图理解为什么以下内容是合法的:
for (idx <- 1 to 10) yield idx
但以下是不合法的。
for (idx <- 1 to 10) { yield idx }
它们在语法上看起来是一样的。我错过了什么?
提前致谢。
我正在尝试学习 scala,并试图理解为什么以下内容是合法的:
for (idx <- 1 to 10) yield idx
但以下是不合法的。
for (idx <- 1 to 10) { yield idx }
它们在语法上看起来是一样的。我错过了什么?
提前致谢。
因为这就是解析器的工作方式,所以这里是Scala 规范的一部分:
Expr1 ::= ‘for’ (‘(’ Enumerators ‘)’ | ‘{’ Enumerators ‘}’)
{nl} [‘yield’] Expr
它说我们可以拥有一个或多个这样命名的枚举器,{nl}
说我们可以嵌套多个for
像
for(...)
for(...)
...
我们可以在yield
表达式后面添加可选关键字,但是没有大括号的位置。表达式 (body) 本身可以是(idx)
, {idx}
, justidx
或其他东西,所以这是合法的:
for (idx <- 1 to 10) yield { idx }
这归结为如何对 for 表达式进行脱糖(以及与之关联的解析器规则)。
在第一种情况下,编译器会将理解脱糖为以下内容:
(1 to 10).map(idx => idx)
第二种情况是允许人们使用 for 循环的简写(这可能很麻烦)。第二种形式for
本质上是执行foreach
结果总是存在的Unit
,因此yield
不可能,因为返回类型已经定义。
yield
好像可以换成map
。因此使这成为可能
for (idx <- 1 to 10) yield {val square = idx * idx; square}
你可以从scala-yield-syntax找到更多关于这个的信息,在这里可以找到更多细节can-someone-explain-scalas-yield