Scala:布尔到选项

Chr*_*ach 60 scala

我有一个布尔值,并希望避免这种模式:

if (myBool) 
  Option(someResult) 
else 
  None
Run Code Online (Sandbox Code Playgroud)

我想做的是

myBool.toOption(someResult)
Run Code Online (Sandbox Code Playgroud)

任何有代码示例的建议都会非常感激.

n1r*_*1r3 59

Scalaz有一种方法可以使用BooleanOps.option.那会让你写:

myBool.option(someResult)
Run Code Online (Sandbox Code Playgroud)

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

implicit class RichBoolean(val b: Boolean) extends AnyVal {
  final def option[A](a: => A): Option[A] = if (b) Some(a) else None
}
Run Code Online (Sandbox Code Playgroud)

  • 因为在Scala中,导入通常与解决方案一样难以发现:`import scalaz.syntax.std.boolean._` (16认同)
  • 我想用Cats做这个,但这些类型的丰富在[鼠标]中显然是显而易见的(https://github.com/benhutchison/mouse)... (4认同)

Xav*_*hot 19

开始时Scala 2.13,为此目的Option有一个when构建器:

Option.when(condition)(result)
Run Code Online (Sandbox Code Playgroud)

例如:

Option.when(true)(3)
// Option[Int] = Some(3)
Option.when(false)(3)
// Option[Int] = None
Run Code Online (Sandbox Code Playgroud)

还要注意Option.unless哪些促进相反的条件.


小智 16

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

Option(myBool).collect { case true => someResult }
Run Code Online (Sandbox Code Playgroud)

来自REPL:

scala> (Option(true).collect { case true => 3 }, Option(false).collect { case true => 3 })
res3: (Option[Int], Option[Int]) = (Some(3),None)
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案的缺点:1)几乎相同数量的代码(比较`if(谓词)一些(结果)否则无)但语义很奇怪2)一点运行时开销:a)null测试(可以减轻`some(谓语)......`)b)2个过多的对象被cteated(Some和Lifted的实例)c)过多的函数调用 (3认同)

jaz*_*mit 15

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

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

然后你可以写

myBool.toOption(someResult)
Run Code Online (Sandbox Code Playgroud)

例如:

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

scala> false.toOption("hi")
res6: Option[String] = None
Run Code Online (Sandbox Code Playgroud)

  • 如果你将它放在`对象BoolImplicits {...}`中,那么执行`import BoolImplicits._`以便能够将`toOption`应用于布尔值. (3认同)

jaz*_*mit 8

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

Some(someResult).filter(myBool)
Run Code Online (Sandbox Code Playgroud)

  • 一些(someResult).filter(_ => myBool) (7认同)