Scala如何使用默认值而不重新定义它们

时间:2016-08-03 17:18:06

标签: scala

我的函数定义为:

def par(min: Int = -1, exact: Int = -1, auto: Boolean = false) = {
  require(min > 0 || exact > 0 || auto, "Invalid argument")
  OpPar(drm, minSplits = min, exactSplits = exact)
}

在另一个使用它的函数中,我传递了par参数的选项。我想允许par使用它自己的默认设置但不知道如何在Scala中执行此操作(没有丑陋的逻辑)所以我必须重新定义,实际上,这样的默认值

drmARaw.par(
  min = minPar.getOrElse(-1),// if par changes this may the be wrong default
  exact = exactPar.getOrElse(-1),// if par changes this may the be wrong default
  auto = autoPar.getOrElse(true))

如果默认值发生变化,则会将错误的默认值传递给minexact。使用复杂的逻辑我可以根据parOption的{​​{1}}参数来nonEmpty决定调用minPar的哪个版本,但这非常难看并且会对于具有默认参数的每个函数,必须以不同方式编写。几乎每个Scala lib都会出现这种情况。如果他们更改默认设置而我没有注意到,我的代码就会中断。

上面的例子说明了这个问题,但我正在寻找一个Scala成语,它将涵盖每个情况,其中一个函数的默认值可能会发生变化。我想编写独立于lib函数中默认参数更改的代码。

2 个答案:

答案 0 :(得分:0)

您可以将逻辑提取到具有case classzero状态的单独empty

case class ParInput(min: Int, exact: Int, auto: Boolean)

object ParInput {
  def apply(min: Option[Int], exact: Option[Int], auto: Option[Boolean]) = {

    ParInput(
      min.getOrElse(empty.min),
      exact.getOrElse(empty.exact),
      auto.getOrElse(empty.auto)
    )
  }
  val empty = ParInput(-1, -1, false)
}

以下是其余部分:

def par(input: ParInput = ParInput.empty) = {
  require(min > 0 || exact > 0 || auto, "Invalid argument")
  OpPar(drm, minSplits = input.min, exactSplits = input.exact)
}

def par(
  min: Option[Int] = None,
  exact: Option[Int] = None,
  auto: Option[Boolean] = None
): OpPar = {
  val input = ParInput(min, exact, auto)
  // now call the original library method.
  par(drm, input.min, input.exact)
}

现在你需要更新的是空状态,并完成了。你甚至可以免费获得Monoid。

答案 1 :(得分:0)

所以,据我所知,你有三个Option你需要解压缩并作为传递的参数发送,除非任何选项是None,那么被调用的方法应该使用它自己的默认值缺少参数。

在我看来,你唯一的选择是蛮力。

(minPar, exactPar, autoPar) match {
  case (Some(m),Some(e),Some(a)) => par(min=m, exact=e, auto=a)
  case (Some(m),Some(e),None)    => par(min=m, exact=e        )
  case (Some(m),None,   Some(a)) => par(min=m,          auto=a)
  case (Some(m),None,   None)    => par(min=m                 )
  case (None,   Some(e),Some(a)) => par(       exact=e, auto=a)
  case (None,   Some(e),None)    => par(       exact=e        )
  case (None,   None,   Some(a)) => par(                auto=a)
  case (None,   None,   None)    => par()
}

使用2个参数很容易。 3它是可管理的。在那之后....痛苦。