【问题标题】:Transform value on update in Scala case class (e.g. override setter)在 Scala 案例类中更新时转换值(例如覆盖设置器)
【发布时间】:2012-10-05 16:20:05
【问题描述】:

假设我有一个 Scala 案例类,如下所示:

case class Item(
  roundedValue: Double = 0.00)

我想在每次更新变量时对 roundedValue 进行如下舍入操作:

roundedValue = math.round(roundedValue*100)*0.01

在其他语言中,我只会覆盖 roundedValue 的 setter,但似乎我无法覆盖 case 类变量的 setter,否则它将无法编译。

我见过的一个解决方案是将roundedValue重命名为_roundedValue并使其私有,然后添加公共方法来模拟getter和setter(带有舍入逻辑):Overriding setter on var

但是,当使用命名参数时,这使得 case 类的构造函数使用非常尴尬。有没有其他方法可以做到这一点,或者这是 Scala 中案例类的限制?

【问题讨论】:

  • 首先case类默认是不可变的,因此没有setter。
  • 这是有道理的,考虑到我在尝试实际执行此操作时遇到“重新分配给 val”编译错误。
  • 默认 roundedValue 是 case 类中的 val。但是,您可以将案例类声明为:case class Item(var roundedValue: Double = 0.00) 并且变量将是可变的。
  • 谢谢@jcern 我没有意识到这是可能的。
  • 如果你需要改变Item的状态,你可能不想让它成为一个case类。

标签: scala


【解决方案1】:

如果你能让它工作,我建议你保持你的案例类不可变,但创建一个“复制”方法,在新实例上执行你的突变。

case class Item(roundedValue: Double = 0.0) {
  def withValue(newValue: Double) = Item(math.round(newValue*100)*0.01)
}

您可能还/相反希望在伴随对象中使用类似的方法:

object Item {
  def withValue(value: Double) = Item(math.round(roundedValue*100)*0.01)
}

【讨论】:

  • 谢谢迪伦。在了解有关 Scala 的更多信息后,我同意您的评估,即案例类属性通常应保持不可变(默认值)。由于我的问题的前提是有缺陷的,我接受这个答案的基础是变异副本是在案例类本身/伴随对象中完成这种舍入的合理方法。
猜你喜欢
  • 2014-07-29
  • 1970-01-01
  • 2017-11-10
  • 2020-03-07
  • 1970-01-01
  • 1970-01-01
  • 2016-07-27
  • 2014-12-18
  • 1970-01-01
相关资源
最近更新 更多