Collection type generated by for with yield
When I evaluate a for
in Scala, I get an immutable IndexedSeq
(a collection with array-like performance characteristics, such as efficient random access):
scala> val s = for (i <- 0 to 9) yield math.random + i
s: scala.collection.immutable.IndexedSeq[Double] = Vector(0.6127056766832756, 1.7137598183155291, ...
Does a for
with a yield
always return an IndexedSeq
, or can it also return some other type of collection class (a LinearSeq
, for example)? If开发者_如何学Go it can also return something else, then what determines the return type, and how can I influence it?
I'm using Scala 2.8.0.RC3.
Thanks michael.kebe for your comment.
This explains how for
is translated to operations with map
, flatMap
, filter
and foreach
. So my example:
val s = for (i <- 0 to 9) yield math.random + i
is translated to something like this (I'm not sure if it's translated to map
or flatMap
in this case):
val s = (0 to 9) map { math.random + _ }
The result type of operations like map
on collections depends on the collection you call it on. The type of 0 to 9
is a 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)
The result of the map
operation on that is an IndexedSeq
(because of the builder stuff inside the collections library).
So, to answer my question: the result of a for (...) yield ...
depends on what type is inside the parantheses. If I want a List
as the result, I could do this:
scala> val s = for (i <- List.range(0, 9)) yield math.random + i
s: List[Double] = List(0.05778968639862214, 1.6758775042995566, ...
You can always transform a range to a list using toList:
> val s = for (i <- (0 to 9).toList) yield math.random + i
> s : List[Double]
精彩评论