5

我有这样的代码:

optionBoolean.getOrElse(false) && otherOptionBoolean.getOrElse(false)

Scalastyle 告诉我它可以被简化。如何?

4

4 回答 4

4

您可以尝试以下方法:

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运行。

于 2020-12-03T10:06:12.117 回答
3

这可能更清楚一点:

optionBoolean.contains(true) && otherOptionBoolean.contains(true)
于 2020-12-03T11:55:54.207 回答
3

只是为了在堆上抛出另一个不一定更好的答案,

optionBoolean == Some(true) && otherOptionBoolean == Some(true)

甚至

(optionBoolean, otherOptionBoolean) == (Some(true), Some(true))
于 2020-12-03T23:30:26.693 回答
0

自定义 dsl 怎么样,它可以让你Option[Boolean]像 if is was a 一样工作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 中,但在这种情况下,您会失去操作的可组合性。所以我让所有方法都返回一个Option.

于 2020-12-03T10:07:14.290 回答