2011-07-25 10 views

答えて

68

まあ、それは "教えて、尋ねないで"と戻ってきます。これらの2行を考えてみましょう:最初のケースで

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

を、あなたは内部optを探して、次に何を参照してくださいに応じて反応しています。後者の場合、あなたは何をしたいのかをoptに伝えておき、それに対処しましょう。

Optionの内部ロジックを複製するのはあまりにも多く、あまりにも脆弱でエラーが発生する可能性があります(誤って書き込まれた場合、コンパイル時エラーではなくランタイムエラーが発生する可能性があります)。

これに加えて、それは構成可能ではありません。あなたは3つのオプションを持っている場合は、理解のための単一のは、それらの世話をする:、物事が速く厄介始める

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

ifで。

6

ではなくgetを使用して、機能を実行するのOptionに直接mapforeach、およびflatMapのようなものを適用することがより有用だ理由は、それがSomeまたはNoneのいずれかで動作し、あなたがする必要がないことですその値が存在することを確認するために特別なチェックを行います。

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に対する結果はxがオプションである場合、yでも未定かもしれないので、望まれる、Option[Int]あります。 getNoneでは機能しませんので、エラーが発生していないことを確認するために余分な作業が必要です。 mapによってあなたのために行われる余分な仕事。

+0

はい、私は 'get'を意味します。私は投稿を修正しています。 – Michael

+0

私は考えました。私はその部分を無視するために私の答えを編集しました。 – dhg

19

foreachを使用する良い理由の1つは、ネストされたオプションで何かを解析しています。

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

コンソールには1が表示されます。これを拡張して、オプションで別の参照を格納するクラスを必要に応じて格納するクラスに拡張すると、理解のために、None/Someチェックの巨大な「ピラミッド」を避けることができます。

16

実際の質問には既に優れた回答がありますが、Option -fooの場合はTony Morris' Option Cheat Sheetを必ずチェックしてください。簡単に言えば

+0

上記のリンクの代わりにこのページを見つけました:http://tmorris.net/posts/2008-01-16-scalaoption-cheat-sheet.html – harmanjd

+0

@harmanjdありがとう、訂正しました。 – Landei

2

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

  • foreachを使用し、何か他のもの:if文でisDefinedを使用

  • それがNoneである場合、このオプションはSome、またはデフォルト値である場合は、値が必要な場合:で私たちの操作を実行しようとするとgetOrElse

0

を使用はより多くの必須のスタイルです。電話番号はとする必要があります。。言い換えれば、私たちは物事を指示しており、Optionsの内部にもっと掘り下げています。 map,flatmapは、我々が言うところの、より機能的な方法です。何をするべきか、どうやって行うべきか

関連する問題