【发布时间】:2016-12-17 20:18:27
【问题描述】:
我尝试遵循两个版本的代码来了解 scala 中的 yield 是如何工作的。我无法理解为什么我会得到两个不同的结果
在这个版本中,我调用yield,表达式只是乘以2。我得到一个2的第一个10倍的向量。这对我来说很有意义
scala> val r = for (j <- 1 to 10) yield {
| (j*2).toString //multiply by 2
| }
r: scala.collection.immutable.IndexedSeq[String] = Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20) // got multiples of 2. This looks ok
有趣的是,在这个版本中,我所做的只是将乘以 2 的结果存储在一个 val 中。但现在我得到一个空向量!这是为什么呢?
scala> val r = for (j <- 1 to 10) yield {
| val prod = (j*2).toString //multiply by 2 but store in a val
| }
r: scala.collection.immutable.IndexedSeq[Unit] = Vector((), (), (), (), (), (), (), (), (), ()) //this is empty
我认为 val prod = (j*2).toString 可能会导致 Unit 结果,但是当我尝试在 scala 解释器上遵循独立表达式时,我可以看到 prod 是一个字符串
scala> val prod = 2.toString()
prod: String = 2
【问题讨论】:
-
你需要从lamba返回一些东西——你的lambda不返回任何东西——因此它是一个
void类型或Scala中的Unit。在val之后的一行添加prod,它会隐式返回。 -
@BoristheSpider 是对的。
val prod被创建和放弃了 10 次,所以yield在每次迭代后都没有任何东西可以产生。 -
换一种说法,
prod确实是一个字符串,但val prod = ...的类型是Unit。所以第二个例子中的 Vector 是 Vector[Unit] 类型。 -
在你的第二个语句中,你需要在最后一行之后添加
prod以作为返回值。您在最后一行所做的只是设置一个值但不返回任何内容,因此输出Unit。