12

我正在为不耐烦的人阅读Scala,我遇到了一些让我摸不着头脑的东西。

以下返回一个字符串:

scala> for ( c<-"Hello"; i <- 0 to 1) yield (c+i).toChar
res68: String = HIeflmlmop

但这会返回一个向量:

scala> for (i <- 0 to 1; c <- "Hello") yield (c + i).toChar
res72: scala.collection.immutable.IndexedSeq[Char] = Vector(H, e, l, l, o, I, f, m, m, p)

这两个例子前面的文字是……

“当for循环的主体以yield开头时,然后循环构造一个值的集合,每次迭代一个......这种类型的循环称为for理解。生成的集合与第一个生成器兼容。

如果生成的集合与第一个生成器兼容,那么为什么第二个示例不返回 Range 类型,如下所示:

scala> val range = 0 to 1
range: scala.collection.immutable.Range.Inclusive = Range(0, 1)

还是我完全误解了文本的含义,“......生成的集合与第一个生成器兼容”。

4

2 回答 2

6

for-comprehensions 被简化为一系列map,flatMapfilter操作。

当你map在 a 上使用时Range,你会得到一个Vector输出:

scala> 0 to 2 map (x => x * x)
res12: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 1, 4)

这是因为 aRange是一种非常简单的集合,本质上只是两个三个数字:一个起始值、一个结束值和一个步骤。如果您查看上面映射的结果,您可以看到结果值不能用该Range类型的某些东西表示。

于 2013-05-11T16:11:39.420 回答
0

在这个for (i <- 0 to 1; c <- "Hello") yield (c + i).toChar理解中,第一个生成器的类型为scala.collection.immutable.Range.Inclusive ,产生结果向量的类型为scala.collection.immutable.IndexedSeq[Int] ,如果您检查类Rangehttp://www。 scala-lang.org/api/current/index.html#scala.collection.immutable.Range

它显示Range扩展/混合IndexedSeq。超类型IndexedSeq与子类型Range兼容。

如果结果不能用范围表示(如上一个答案所述),它将“搜索”超类型来表示结果。

在此处输入图像描述

于 2015-11-13T03:08:25.070 回答