返回Scala for / yield的类型

时间:2013-05-11 16:02:20

标签: scala scala-collections for-comprehension

我正在阅读Scala for the Impatient并且我遇到了让我摸不着头脑的东西。

以下命令返回一个字符串:

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

但是这会返回一个Vector:

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 comprehension。生成的集合与第一个生成器兼容。

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

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

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

2 个答案:

答案 0 :(得分:5)

对于一系列mapflatMapfilter操作,for-comprehensions被贬低了。

map上使用Range时,您会收到Vector输出:

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

这是因为Range是一种非常简单的集合,基本上只有两个三个数字:起始值,结束值和步骤。如果您查看上面的映射结果,您会发现结果值无法用Range类型的某些内容表示。

答案 1 :(得分:0)

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

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

如果结果不能用范围表示(如前面的答案所解释的那样),它将“搜索”超级类型来表示结果。

enter image description here