2013-05-11 130 views
10

我正在閱讀通過Scala for the Impatient,我遇到了一些讓我撓頭的東西。斯卡拉返回類型/收益

下返回一個字符串:

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開始,然後循環 構造一個值的集合,每個迭代一個...這種類型的lo op被稱爲理解。生成的集合與第一個生成器兼容。

如果生成的收集與第一發電機兼容,那麼爲什麼不是第二個例子返回一個類型的範圍,如下列:

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

還是我完全什麼誤解文本意味着,「...生成的集合與第一個生成器兼容」。

+0

看看[這種優越的答案](http://stackoverflow.com/a/1716558/406435)得到它是如何工作的更好的視野。和[這裏](http://www.devoxx。com/display/FR13/Martin + Odersky)(從42:40開始)Martin Odersky自己解釋了scala系列的歷史,動機和實現。 – senia 2013-05-11 16:32:08

回答

4

理解被解除爲一系列map,flatMapfilter操作。

當您在Range使用map,你會得到一個Vector輸出:

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

這是因爲Range是一個非常簡單的排序集合,也就是基本上只是三個數字:一開始值,結束值和步驟。如果您查看上面映射的結果,可以看到結果值不能用Range類型的值表示。

0
在此 for (i <- 0 to 1; c <- "Hello") yield (c + i).toChar理解

, 所述第一發生器是類型scala.collection.immutable.Range.Inclusive 收率結果矢量是類型scala.collection.immutable.IndexedSeq的[INT] 並且如果你檢查類範圍http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Range

它顯示範圍擴展/混入的IndexedSeq。超級類型IndexedSeq與子類型範圍兼容。

如果結果不能用範圍表示(如前面的答案所述),它將'搜索'超類型來表示結果。

enter image description here