私は Scalaでのプログラミング を進めており、Pythonの観点から物事を見てみたいと思いますが、 "Python in Scala"をプログラミングしたくありません。
制御フローに関する限り、私は何をすべきかよくわかりません。Pythonでは、for x in some_iterable
を使用して死にます。 Scalaには、Oderskyがforexpressionと呼ぶ非常によく似た構造があり、おそらくJava forループと区別するためです。また、Scalaには、反復可能なデータ型のforeach
属性(属性であると推測されるため、Scalaについて正しく名前を付けるのに十分な知識がない)があります。ただし、foreach
を使用して、コンテナ内の各アイテムに対して1つの関数を呼び出す以上のことを実行できるとは思えません。
これにはいくつかの質問があります。 1つ目は、PythonのようにScalaで重要な/頻繁に使用されるコンストラクトの式です。2つ目は、for式の代わりにforeach
を使用する必要がある場合です(関数を呼び出す明らかな場合を除く)コンテナの各アイテムに)?
ひどく曖昧になったり広すぎたりしないことを願っていますが、Scala(これまでのところ非常にクールに思えます)のデザイン/言語の基礎をいくつかつかもうとしています。
pythonはリスト内包表記とジェネレーター式でfor
を使用します。それらはvery scala for
式に似ています:
これはpythonです
_>>> letters = ['a', 'b', 'c', 'd']
>>> ints = [0, 1, 2, 3]
>>> [l + str(i) for l in letters for i in ints if i % 2 == 0]
['a0', 'a2', 'b0', 'b2', 'c0', 'c2', 'd0', 'd2']
_
これはscalaです
_scala> val letters = List('a', 'b', 'c', 'd')
scala> val ints = List(0, 1, 2, 3)
scala> for (l <- letters; i <- ints if i % 2 == 0) yield l.toString + i
res0: List[Java.lang.String] = List(a0, a2, b0, b2, c0, c2, d0, d2)
_
各コンストラクトは、多数のジェネレーター/イテレーターを受け取り、フィルター式を適用して、組み合わせた式を生成できます。 pythonでは_(expr for v1 in gen1 if expr1 for v2 in gen2 if expr2)
_はおおよそ次と同等です:
_for v1 in gen1:
if expr1:
for v2 in gen2:
if expr2:
yield expr
_
In scala for (v1 <- gen1 if expr1; v2 <- gen2 if expr2) yield expr
はおおよそ次と同等です:
_gen1.withFilter(expr1).flatMap(v1 => gen2.withFilter(expr2).map(v2 => expr))
_
python _for x in xs
_構文が好きなら、おそらくscala for
式が好きでしょう。
Scalaには、いくつかの追加の構文と翻訳の工夫があります。構文的にfor
を中括弧と共に使用すると、ステートメントを別々の行に配置できます。値の割り当ても実行できます。
_val res = for {
i <- 1 to 20; i2 = i*i
j <- 1 to 20; j2 = j*j
k <- 1 to 20; k2 = k*k
if i2 + j2 == k2
} yield (i, j, k)
_
また、_v1 <- gen1
_は実際に__case v1 => gen1
_と一致します。一致しない場合、これらの要素は反復から無視されます。
_scala> val list = List(Some(1), None, Some(2))
scala> for (Some(i) <- list) yield i
res2: List[Int] = List(1, 2)
_
for
は言語の重要な場所だと思います。あなたが読んでいる本の中にそれについての章全体(23)があるという事実から私は知ることができます!
はい、Scala(一般的に知られているように)理解のために多く使用されますが、実際にはメソッドの特定の組み合わせのための単なる構文糖であり、多くはこれらのメソッドを直接呼び出す代わりに構文糖を使用します。
Scala内包表記については、 この質問 を参照してください。特に、for (x <- xs) f(x)
はxs.foreach(x => f(x))
。
さて、あなたはforeach
メソッドではあまり使用しないように見えると言いますが、Scalaコレクションのほとんどすべてのメソッドは(または)foreach
のみで実装されています.Traversable
のドキュメントを参照してください-すべてのメソッドはforeach
のみで実装できます。
Scalaのyield
はPythonのyield
とは似ていないことに注意してください-that質問も。
ネストされた反復、フィルター、および変換をサポートしているため、Scalaのfor
は言語の長所の1つであり、非常に重要です。 foreach
、map
、およびfilter
を使用するよりも好む傾向があります。
Foreachは機能的なスタイルですが、forは必須のスタイルです。 LISPまたはスキームを実行したことがあれば、関数型プログラミングにすでに精通しています。そうでない場合は、最初は少し混乱するかもしれません。私が最初に行うことは、foreachのようなものに渡す匿名関数であるクロージャー構文について調べます。あなたはそれがすべてより理にかなっていることを理解したら。
あなたの質問は、主に以下によって答えられます:
要約すると:それは主に文体的です。個人的には、機能的な方法論を好みますが、入れ子になったループを扱うときは理解が簡潔であることを好みます。