在 Scala 中简化 Option[Boolean] 表达式
Simplifying Option[Boolean] expression in Scala
我有这样的代码:
optionBoolean.getOrElse(false) && otherOptionBoolean.getOrElse(false)
Scalastyle 告诉我它可以简化。怎么样?
您可以尝试以下方法:
Seq(optionBoolean, otherOptionBoolean).forall(_.contains(true))
在Scala 2.13中(与之前的版本非常相似)forall
方法位于IterableOnce
,其实现是:
def forall(p: A => Boolean): Boolean = {
var res = true
val it = iterator
while (res && it.hasNext) res = p(it.next())
res
}
所以一旦有一个值不满足条件,循环就会中断,其余的将不会被测试。
代码 运行 在 Scastie。
自定义 dsl 怎么样,它让您可以像 Boolean
一样使用 Option[Boolean]
?使用所有相同的运算符和相同的行为。
你可以这样使用:
object Booleans {
def and(fb: Option[Boolean], other: => Option[Boolean]): Option[Boolean] =
fb.flatMap(b => if (!b) Some(false) else other)
def or(fb: Option[Boolean], other: => Option[Boolean]): Option[Boolean] =
fb.flatMap(b => if (b) Some(true) else other)
def negate(fb: Option[Boolean]): Option[Boolean] =
fb.map(!_)
object Implicits {
implicit class OptionBooleanDecorator(val fb: Option[Boolean]) extends AnyVal {
def &&(other: => Option[Boolean]): Option[Boolean] =
and(fb, other)
def ||(other: => Option[Boolean]): Option[Boolean] =
or(fb, other)
def unary_!(): Option[Boolean] = negate(fb)
}
}
}
和代码中的某处:
import Booleans.Implicits._
val b1 = Some(true)
val b2 = Some(true)
val b3 = b1 && b2
val b4 = b1 || b2
val b5 = !b1
您可以让它与任何其他容器一起工作。
这种扩展某种类型的 dsl 在 Scala 世界中很常见。
编辑:
至于最后一部分,即 orElse
方法——这也可以放在 dsl 中,但在这种情况下,你会失去操作的可组合性。所以我让所有方法 return 一个 Option
.
这样可能更清楚一点:
optionBoolean.contains(true) && otherOptionBoolean.contains(true)
只是抛出另一个不一定更好的答案,
optionBoolean == Some(true) && otherOptionBoolean == Some(true)
甚至
(optionBoolean, otherOptionBoolean) == (Some(true), Some(true))
我有这样的代码:
optionBoolean.getOrElse(false) && otherOptionBoolean.getOrElse(false)
Scalastyle 告诉我它可以简化。怎么样?
您可以尝试以下方法:
Seq(optionBoolean, otherOptionBoolean).forall(_.contains(true))
在Scala 2.13中(与之前的版本非常相似)forall
方法位于IterableOnce
,其实现是:
def forall(p: A => Boolean): Boolean = {
var res = true
val it = iterator
while (res && it.hasNext) res = p(it.next())
res
}
所以一旦有一个值不满足条件,循环就会中断,其余的将不会被测试。
代码 运行 在 Scastie。
自定义 dsl 怎么样,它让您可以像 Boolean
一样使用 Option[Boolean]
?使用所有相同的运算符和相同的行为。
你可以这样使用:
object Booleans {
def and(fb: Option[Boolean], other: => Option[Boolean]): Option[Boolean] =
fb.flatMap(b => if (!b) Some(false) else other)
def or(fb: Option[Boolean], other: => Option[Boolean]): Option[Boolean] =
fb.flatMap(b => if (b) Some(true) else other)
def negate(fb: Option[Boolean]): Option[Boolean] =
fb.map(!_)
object Implicits {
implicit class OptionBooleanDecorator(val fb: Option[Boolean]) extends AnyVal {
def &&(other: => Option[Boolean]): Option[Boolean] =
and(fb, other)
def ||(other: => Option[Boolean]): Option[Boolean] =
or(fb, other)
def unary_!(): Option[Boolean] = negate(fb)
}
}
}
和代码中的某处:
import Booleans.Implicits._
val b1 = Some(true)
val b2 = Some(true)
val b3 = b1 && b2
val b4 = b1 || b2
val b5 = !b1
您可以让它与任何其他容器一起工作。 这种扩展某种类型的 dsl 在 Scala 世界中很常见。
编辑:
至于最后一部分,即 orElse
方法——这也可以放在 dsl 中,但在这种情况下,你会失去操作的可组合性。所以我让所有方法 return 一个 Option
.
这样可能更清楚一点:
optionBoolean.contains(true) && otherOptionBoolean.contains(true)
只是抛出另一个不一定更好的答案,
optionBoolean == Some(true) && otherOptionBoolean == Some(true)
甚至
(optionBoolean, otherOptionBoolean) == (Some(true), Some(true))