8

Coursera の Scala コースに続いて、Martin Odersky 氏は次のようなサンプル コードを示しました。

1 to 5 map ( i => i*i )

そして彼は、Rangeが に変換されるのはVector、それらが同じインターフェース ( IndexedSeq) を共有し、結果を として表現できないためだと言いましたRange (彼が として表現できないペアを生成したので、その例ではより明確でしたRange)。

for 式では、最初のジェネレーターが生成される要素の種類を決定し、少なくともRange.

上記で計算された結果を表すことができる唯一の他の実装ではない可能性があるVectorため、出力が である理由を理解できません。Vector

誰かがこの部分を理解するのを手伝ってくれますか?

4

3 に答える 3

10

mapCanBuildFrom暗黙の引数としてひそかに a を取ります。その仕事は、あなたがすでに持っているコレクション (およびコンテンツのタイプ) を考慮して、新しいコレクションを作成することです。Rangeは任意のものを含むことができないため (任意の整数でさえも)、. を生成するものはありませCanBuildFromRange。の最も具体的なスーパータイプはRangeisCanBuildFromですIndexedSeq。これによって実際に構築されるコレクションはVector.

于 2012-10-29T22:26:18.420 に答える
2

マーティンも説明したと確信しているように、内包表記はおよびメソッドforの連鎖呼び出しに対応します (変換されます) (およびを使用しない場合)。mapflatMapforeachyield

通常、最初のジェネレーターの型の値になる理由は、map通常flatMap、 と がそのレシーバーと同じ型を返すためです ( mapaListは aListなどを返します)。

sの問題Rangeは、整数の規則的なシーケンスではないものを表現できないことです。結果として、 and の戻り値の型はmapflatMap for に定義されているRangeように にすることはできませんRange。次に最適なのはVector、インデックス付きシーケンスのプロトタイプの実装である です。

(ソース コードやリンク先の Scala doc ページを見れば、戻り値の型だけでなく、概念的にはもう少し複雑であることがわかりますが、それが理由です。編集: ...そして今 RexカーはちょうどCanBuildFrom爆弾を落とした. )

于 2012-10-29T22:25:11.173 に答える
1

Vectorのデフォルトの実装ですIndexedSeq。クラスは、開始値、停止値、およびステップ値で表すことができる一連の数値を含むように設計されているため (Python と同様) 、をmapとして表すことはできません。API ドキュメントは、それが の特殊なケースであると指定しています。RangeRangerangeIndexSeq

1 to 5 map { i => i * i }値のコンテナー (1、4、9、16、25) が得られることがわかります。開始と停止を取得できますが、一定のステップ値は取得できません。

于 2012-10-29T22:23:12.140 に答える