【问题标题】:Collection type generated by for with yieldfor with yield 生成的集合类型
【发布时间】:2010-06-01 07:18:24
【问题描述】:

当我在 Scala 中评估 for 时,我得到一个不可变的 IndexedSeq(具有类似数组的性能特征的集合,例如高效的随机访问):

scala> val s = for (i <- 0 to 9) yield math.random + i
s: scala.collection.immutable.IndexedSeq[Double] = Vector(0.6127056766832756, 1.7137598183155291, ...

带有yieldfor 是否总是返回IndexedSeq,或者它也可以返回一些其他类型的集合类(例如LinearSeq)?如果它也可以返回别的东西,那么是什么决定了返回类型,我又该如何影响呢?

我正在使用 Scala 2.8.0.RC3。

【问题讨论】:

标签: scala scala-2.8 scala-collections


【解决方案1】:

感谢 michael.kebe 的评论。

This 解释了如何将for 转换为具有mapflatMapfilterforeach 的操作。所以我的例子:

val s = for (i <- 0 to 9) yield math.random + i

被翻译成这样的东西(我不确定在这种情况下是被翻译成map还是flatMap):

val s = (0 to 9) map { math.random + _ }

map 等对集合的操作的结果类型取决于您调用它的集合。 0 to 9 的类型是Range.Inclusive

scala> val d = 0 to 9
d: scala.collection.immutable.Range.Inclusive with scala.collection.immutable.Range.ByOne = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

map 操作的结果是 IndexedSeq(因为集合库中的构建器内容)。

所以,回答我的问题:for (...) yield ... 的结果取决于括号内的类型。如果我想要 List 作为结果,我可以这样做:

scala> val s = for (i <- List.range(0, 9)) yield math.random + i
s: List[Double] = List(0.05778968639862214, 1.6758775042995566, ...

【讨论】:

  • 在你的情况下它被翻译成地图。如果你有两个生成器的理解,这将被转换为 flatMap/map 组合。所以 for (i j) 被转换为 (0 until 9).flatMap{case i => (0 until i).map{case j => 我j}}
  • “取决于括号内的类型”,更准确地说是确定类型的第一个右侧参数。
【解决方案2】:

您始终可以使用 toList 将范围转换为列表:

> val s = for (i <- (0 to 9).toList) yield math.random + i
> s  : List[Double]

【讨论】:

    猜你喜欢
    • 2016-06-11
    • 2021-11-14
    • 1970-01-01
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    相关资源
    最近更新 更多