我发现我经常需要将在Option
上运行的函数链接在一起并返回一个看起来像这样的Option
:
if(foo.isDefined) someFunctionReturningOption(foo.get) else None
有更清洁的方法吗?对于更复杂的变量,这种模式变得非常冗长。
我在表单处理代码中看到了一些必须处理可选数据的问题。如果值为None
或某些转换(可能会失败),则会插入None
(如果有值)。
答案 0 :(得分:6)
您可以使用flatMap
:
foo.flatMap(someFunctionReturningOption(_))
或者在for-comprehension中:
for {
f <- foo
r <- someFunctionReturningOption(f)
} yield r
将这些函数的多个实例链接在一起时,首选for-comprehension,因为它们会降低到flatMap
s。
答案 1 :(得分:4)
有很多选择(双关语意)但是对于理解,我猜,在链条的情况下是最方便的
for {
x <- xOpt
y <- someFunctionReturningOption(x)
z <- anotherFunctionReturningOption(y)
} yield z
答案 2 :(得分:2)
您正在寻找flatMap
:
foo.flatMap(someFunctionReturningOption)
这适用于一般的monadic结构,其中包裹类型的monad使用flatMap
返回相同类型(例如flatMap
上的Seq[T]
返回Seq
)。
答案 3 :(得分:2)
Option
支持map(),因此当x
为Option[Int]
此构造时:
if (x.isDefined)
"number %d".format(x.get)
else
None
更容易写为:
x map (i => "number %d".format(i))
map将保持None
未修改,但它会将传递给它的函数应用于任何值,并将结果包装回Option中。例如,请注意“x”如何转换为下面的字符串消息,但“y”将作为None
传递:
scala> val x: Option[Int] = Some(3)
x: Option[Int] = Some(3)
scala> val y: Option[Int] = None
y: Option[Int] = None
scala> x map (i => "number %d".format(i))
res0: Option[String] = Some(number 3)
scala> y map (i => "number %d".format(i))
res1: Option[String] = None