的解決方案是使用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
/flatMap
無處不在,因爲肯定會使用Scala的一段時間後的情況下),併產生準確的引擎蓋下的代碼相同。
欲瞭解更多的背景,你可以檢查此的其他問題:What is Scala's yield?
UPDATE: 感謝奔詹姆斯指出flatMap是聯想。換句話說,x flatMap(y flatMap z)))
與x flatMap y flatMap z
相同。雖然後者通常不會更短,但它具有避免任何嵌套的優點,這更容易遵循。
這裏是在REPL(4種樣式是等效的,與前兩個使用flatMap嵌套,使用另兩個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)
只是說明但flatMap woun」下面給出幾次工作。它應該是'First.second.flatMap(_。third.flatMap(_。numberOfSmth))。get'並且仍然可能拋出異常 – korefn 2013-02-27 12:20:28
確實,謝謝。感謝大家的答案,我找到了我想要的東西。 – psisoyev 2013-02-27 12:23:28