web-dev-qa-db-ja.com

foreachがget Scalaオプション)よりも優れているのはなぜですか?

Scalaオプションにforeachを使用するよりもmapflatMapgetなどを使用する方が良いと考えられるのはなぜですか? use isEmptygetを安全に呼び出すことができます。

47
Michael

まあ、それは一種の「教えて、聞かないで」に戻ってきます。次の2行について考えてみます。

if (opt.isDefined) println(opt.get)
// versus
opt foreach println

最初のケースでは、optの内部を調べて、表示内容に応じて反応します。 2番目のケースでは、optに何をしたいかを伝え、それを処理させます。

最初のケースはOptionを知りすぎており、内部でロジックを複製し、脆弱でエラーが発生しやすくなっています(誤って記述した場合、コンパイル時エラーではなく、実行時エラーが発生する可能性があります)。

それに加えて、それは構成可能ではありません。 3つのオプションがある場合、理解のための単一のオプションがそれらを処理します。

for {
  op1 <- opt1
  op2 <- opt2
  op3 <- opt3
} println(op1+op2+op3)

ifを使用すると、処理が乱雑になり始めます。

78

foreachを使用する1つの良い理由は、ネストされたオプションで何かを解析することです。あなたのようなものがあれば

val nestedOption = Some(Some(Some(1)))
for {
  opt1 <- nestedOption
  opt2 <- opt1
  opt3 <- opt2
} println(opt3)

コンソールは1。これを拡張して、オプションで何かへの参照を格納し、次に別の参照を格納するクラスがある場合に拡張すると、理解のために、None/Someチェックの巨大な「ピラミッド」を回避できます。

21
Dylan

実際の質問にはすでに優れた回答がありますが、より多くのOption- fooについては、ぜひチェックしてください Tony Morrisのオプションチートシート

17
Landei

mapを使用する代わりに、foreachflatMapOptionなどをgetに直接適用する方が便利な理由関数を実行すると、SomeorNoneのいずれかで機能し、値が存在することを確認するために特別なチェックを行う必要がありません。

val x: Option[Int] = foo()
val y = x.map(_+1) // works fine for None
val z = x.get + 1  // doesn't work if x is None

ここでのyの結果はOption[Int]xがオプションの場合、yも不定になる可能性があるため、これは望ましいことです。 getNoneでは機能しないため、エラーが発生しないようにするために、追加の作業を行う必要があります。 mapがあなたのために行う追加の作業。

6
dhg

簡単に言えば:

  • オプションが定義されている(つまり、Someである)場合のみ、何かを行う必要がある場合(各呼び出しの戻り値をキャプチャする必要がない場合の手順):foreach(各呼び出しの結果を気にする場合は、mapを使用してください)

  • オプションが定義されている場合に何かを行う必要があり、定義されていない場合に何かを行う必要がある場合:ifステートメントでisDefinedを使用します

  • オプションがSomeの場合に値が必要な場合、またはNoneの場合にデフォルト値が必要な場合:getOrElseを使用します

2
JNM

getを使用して操作を実行しようとすると、電話をかける必要がある場合に必須のスタイルになります何をすべきか、どのように行うか。言い換えれば、私たちは物事を口述し、Optionsの内部をさらに掘り下げています。どことしてmap,flatmapは、私たちが言っていることを行うためのより機能的な方法です何をすべきかではなく、どのようにすべきか

0
Balaji Reddy