假设我有一个带有两个可选字段的Toto类:
case class Toto(a : Option[Int], b: Option[Int])
Run Code Online (Sandbox Code Playgroud)
还有一个带有一个可选Toto的Titi类:
case class Titi(c : Option[Toto])
Run Code Online (Sandbox Code Playgroud)
我们创建一个Titi类的实例:
val test = Titi(Some(Toto(Some(1),Some(2))))
Run Code Online (Sandbox Code Playgroud)
现在,我想通过假定Titi或b可以等于None来访问Titi变量中Toto的第二个字段,但这条语句是不可能的:
test.c.getOrElse("Something").b.getOrElse(0)
Run Code Online (Sandbox Code Playgroud)
我该怎么做呢?
您应该使用flatMap:
test.c.flatMap(_.b).getOrElse(0)
Run Code Online (Sandbox Code Playgroud)
在层次结构中任何位置的情况下,None将返回0。如果您具有返回属性的更深层次的对象层次结构,则Option可以链接flatMap:
test.c
.flatMap(_.b)
.flatMap(_.d)
//...etc
Run Code Online (Sandbox Code Playgroud)
Scala还具有用于解开深度嵌套的monadic类型的特殊语法,称为for comprehension:
val result = for {
c <- test.c
a <- c.a
} yield a
result.getOrElse(0)
Run Code Online (Sandbox Code Playgroud)
在后台,它被编译为类似于chained的代码flatMap。
这基本上是这样的:
如果c是None,则直接进入getOrElse并返回0;如果是,Some则进行检查b;如果不是,则进行检查;否则,返回getOrElse包装的值Some。
如果您想返回不同的区别,那Option就是None,那么我将使用match:
test.c match {
case Some(c) => c.getOrElse(0)
// if you return String in one branch and integer in other then inferred type would be Any!
case None => "Something"
}
Run Code Online (Sandbox Code Playgroud)