【问题标题】:Override default argument only when condition is fulfilled仅在满足条件时覆盖默认参数
【发布时间】:2014-05-01 01:16:57
【问题描述】:

给定

case class Foo (
  x: Int = 1,
  y: String,
)

实例化所述类的最佳方法是什么,仅当满足局部条件时才覆盖默认参数(例如,与构造函数参数对应的局部变量不是无)

object Test {
  /* Let's pretend I cannot know the state of x,y
   * because they come from the network, a file... */
  val x: Option[Int] = getX()
  val y: Option[String] = getY()

  Foo(
    x=???,   // how to get x=if(x.isDefined) x else "use default of Foo" here
    y=y.get,
  )
}

检查条件并以不同方式实例化案例类的直接解决方案无法扩展(具有默认值的七个参数 -> 128 个不同的实例化)

解决方案 1) 我知道的一种解决方案是:

object Foo {
  val Defaults = Foo(y="")
}

object Test {
  val x: Option[Int] = getX()
  val y: Option[String] = getY()

  Foo(
    x=x.getOrElse(Foo.Defaults.x)
    y=y.get
  )
}

这工作正常。当 y 为 None 时,我得到 NoSuchElementException,但这没关系,因为它是强制构造函数参数。然而,这显然是一种 hack,并且有一个明显的缺点,即可以编写:

  Foo(
    x=x.getOrElse(Foo.Defaults.x)
    y=y.getOrElse(Foo.Defaults.y)
  )

当 y 为 None 时,你会得到一个无意义的 y 默认值。

解决方案 2) 另一个解决方案类似于:

sealed trait Field
case object X extends Field

object Foo {
  private val template = Foo(y="")
  val Defaults = {
    case X => template.x
  }
}

object Test {
  val x: Option[Int] = getX()
  val y: Option[String] = getY()

  Foo(
    x=x.getOrElse(Foo.Defaults(X))
    y=y.get
  )
}

从安全角度来看,这是一个更好的类型,但现在我必须为每个默认参数创建一个类型。

正确而简洁的解决方案应该是什么样的?

【问题讨论】:

标签: scala case-class


【解决方案1】:

我不清楚你如何能比以下做得更好:

object Foo { def apply(optX: Option[Int], optY: Option[String]): Foo = Foo(optX.getOrElse(1), optY.get) }
case class Foo private(x: Int, y: String)

Foo(Some(5), None) // fails with NoSuchElementException
Foo(Some(5), Some("Hi")) // succeeds in creating Foo(5, "Hi")
Foo(None, Some("Hi")) // succeeds in creating Foo(1, "Hi"), note the default value of x

通过调用get(前者)和getOrElse(后者)来编码参数是必需的还是可选的。

当然,您可以包装Optionget 方法,以便在省略所需参数时提供更有意义的消息。

我意识到这与您的解决方案 1 相距不远,可能无法满足您的需求。

【讨论】:

    猜你喜欢
    • 2019-05-09
    • 1970-01-01
    • 2017-12-12
    • 2018-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-22
    • 2017-02-09
    相关资源
    最近更新 更多