如果值为Some(...),则执行副作用的最常用方法是什么?如果值为None,则执行另一个副作用。这是我目前倾向于写的内容:
def doSideEffectA(value: Int) {
// ...
}
def doSideEffectB() {
// ...
}
def doSideEffect(valueOption: Option[Int]) {
valueOption map { value =>
doSideEffectA(value)
} getOrElse {
doSideEffectB()
}
}
我的问题是,如果我没有做任何事情,如果valueOption是None,那么这就是我写的:
def doSideEffectNothingIfNone(valueOption: Option[Int]) {
valueOption foreach { value =>
doSideEffectA(value)
}
}
map / getOrElse通常不用于副作用上下文,而foreach是。我不太满意valueOption map {...} getOrElse {...}返回Unit,因为我没有从我的Option [Int]中“获取”任何东西。
答案 0 :(得分:13)
Kim Stebel说:模式匹配是一个简单的解决方案。
valueOption match {
case Some(value) => doSideEffectA(value)
case None => doSideEffectB()
}
答案 1 :(得分:9)
Scala 2.10在fold
上包含Option
方法,适用于您需要None
和Some
同时解析为相同类型的任何情况(包括{{ 1}}):
Unit
答案 2 :(得分:4)
使用scalaz,您会在fold
上获得Option
方法,该方法需要两个函数并执行其中一个,具体取决于您是Some
还是None
:< / p>
scala> some(3).fold({ x => println(x) }, println("FOO"))
3
scala> none[String].fold({ x => println(x) }, println("FOO"))
FOO
答案 3 :(得分:4)
Scalaz有cata
,您可以这样说明:
valueOption.cata(doSideEffectA, doSideEffectB)
从未使用它,但它对我来说看起来非常有用和可读。这就是它的实现方式:
/**
* Catamorphism over the option. Returns the provided function `some` applied to item contained in the Option
* if it is defined, otherwise, the provided value `none`.
*/
def cata[X](some: A => X, none: => X): X = value match {
case None => none
case Some(a) => some(a)
}
答案 4 :(得分:3)
尽管我仍然认为模式匹配是最具可读性的选项,但您也可以按照自己的方式进行操作,并使用隐式转换定义Option
周围的包装。
class Else(doit:Boolean) {
def orDoThis[A](f: =>A) {
if (doit) f
}
}
class OptionWrapper[A](o:Option[A]) {
def each[B](f: A=>B):Else = o match {
case Some(v) => f(v); new Else(false)
case None => new Else(true)
}
}
implicit def wrapOption[A](o:Option[A]):OptionWrapper[A] = new OptionWrapper(o)
然后你可以写例如:
Some(1) each println orDoThis println("nothing there")
答案 5 :(得分:1)
大多数惯用方式实际上是模式匹配。否则,您可以创建一个隐式包装器,它提供所需的方法:
class RichOption[T](o: Option[T]) {
def ifEmpty(action: => Unit) { if (o.isEmpty) action }
}
object RichOption {
implicit def enrich(o: Option[T]) = return new RichOption(o)
}
编辑:@KimStebel答案中的答案更符合所需的用法。