Option.map
解決策は、次を使用することOption.flatMap
です。
First.flatMap(_.second.flatMap(_.third.map(_.numberOfSmth)))
または同等のもの (この回答の最後にある更新を参照):
First flatMap(_.second) flatMap(_.third) map(_.numberOfSmth)
これは を返しますOption[Int]
( が をnumberOfSmth
返す場合Int
)。呼び出しチェーンのオプションのいずれかが である場合、None
結果は になりNone
ます。Some(count)
count
numberOfSmth
もちろん、これは非常に速く醜くなる可能性があります。このため、scala はシンタックス シュガーとしての理解をサポートします。上記は次のように書き換えることができます。
for {
first <- First
second <- first .second
third <- second.third
} third.numberOfSmth
map
これは間違いなく優れており (特に、scala を使用してしばらくすると確実にそうなるように、どこでも/を見ることにまだ慣れていないflatMap
場合)、内部でまったく同じコードを生成します。
詳細な背景については、この他の質問を確認してください: Scala の利回りは何ですか?
更新: flatMap が連想的であることを指摘してくれた Ben James に感謝します。つまりx flatMap(y flatMap z)))
と同じx flatMap y flatMap z
です。後者は通常短くはありませんが、ネストを回避できるという利点があり、従うのが簡単です。
REPL の図を次に示します (4 つのスタイルは同等で、最初の 2 つは flatMap ネストを使用し、他の 2 つは flatMap のフラット チェーンを使用します)。
scala> val l = Some(1,Some(2,Some(3,"aze")))
l: Some[(Int, Some[(Int, Some[(Int, String)])])] = Some((1,Some((2,Some((3,aze))))))
scala> l.flatMap(_._2.flatMap(_._2.map(_._2)))
res22: Option[String] = Some(aze)
scala> l flatMap(_._2 flatMap(_._2 map(_._2)))
res23: Option[String] = Some(aze)
scala> l flatMap(_._2) flatMap(_._2) map(_._2)
res24: Option[String] = Some(aze)
scala> l.flatMap(_._2).flatMap(_._2).map(_._2)
res25: Option[String] = Some(aze)