69

我有一个布尔值,想避免这种模式:

if (myBool) 
  Option(someResult) 
else 
  None

我想做的是

myBool.toOption(someResult)

任何带有代码示例的建议将不胜感激。

4

10 回答 10

60

Scalaz 有办法使用BooleanOps.option来做到这一点。这将允许你写:

myBool.option(someResult)

如果您不想添加 Scalaz 依赖项,只需在代码中添加以下内容:

implicit class RichBoolean(val b: Boolean) extends AnyVal {
  final def option[A](a: => A): Option[A] = if (b) Some(a) else None
}
于 2013-10-30T18:13:14.097 回答
39

开始Scala 2.13Option有一个when用于这个确切目的的构建器:

Option.when(condition)(result)

例如:

Option.when(true)(3)
// Option[Int] = Some(3)
Option.when(false)(3)
// Option[Int] = None

还要注意Option.unless哪个促进了相反的条件。

于 2019-01-17T22:16:55.007 回答
20

Option().collect() 是这种事情的好模式。

Option(myBool).collect { case true => someResult }

来自 REPL:

scala> (Option(true).collect { case true => 3 }, Option(false).collect { case true => 3 })
res3: (Option[Int], Option[Int]) = (Some(3),None)
于 2015-03-26T20:20:24.733 回答
16

其他答案均未回答所述问题!要获得您指定的确切语义,请使用:

implicit class BoolToOption(val self: Boolean) extends AnyVal {
  def toOption[A](value: => A): Option[A] =
    if (self) Some(value) else None
}

然后你可以写

myBool.toOption(someResult)

例如:

scala> true.toOption("hi")
res5: Option[String] = Some(hi)

scala> false.toOption("hi")
res6: Option[String] = None
于 2015-12-28T18:50:55.600 回答
9

如果您不介意someResult被评估,无论您的价值如何,myBool也可以使用

Some(someResult).filter(myBool)
于 2015-12-28T18:52:33.683 回答
4
scala> PartialFunction.condOpt(5) { case x if true => x }
res9: Option[Int] = Some(5)

scala> PartialFunction.condOpt(5) { case x if false => x }
res10: Option[Int] = None

这里,守卫持有条件,传递给condOpt的值是守卫评估为真时返回的值。

于 2013-10-30T18:10:22.693 回答
4

另一种选择:

implicit class RichOptionCompanion(val self: Option.type) extends AnyVal {
  def when[A](cond: Boolean)(value: => A): Option[A] = if(cond) Some(value) else None
}

用法:

Option.when(foo != "bar") { ... }
于 2013-10-30T18:29:48.930 回答
2
class RichBool[T](a: Boolean, res:=> T) {
   def toOption: Option[T] = if (a) Some(res) else None
}
implicit def boolToRichBool[T](tp: (Boolean, T)): RichBool[T] = new RichBool(tp._1, tp._2);

这会给你:

(true, 5).toOption // Some(5);
(false, 3).toOption // None
于 2013-10-30T18:06:30.810 回答
2

以下是我会考虑的几件事:

val bool: Boolean = ???
val result = 1337    

Option(bool).withFilter(identity).map(_ => result)

或者

for {
  opt <- Option(bool)
  if opt
} yield result
于 2018-10-10T16:01:55.827 回答
1
Option(true).find(_ == true) // Some(true)
Option(false).find(_ == true) // None
于 2019-12-12T11:55:44.053 回答