3

我有一个现有的 Scala 应用程序,它使用案例类,然后将其持久化在 MongoDB 中。我需要向案例类引入一个新字段,但它的值是从现有字段派生的。

例如,有电话号码,我想在保留原始电话号码的同时添加规范化的电话号码。我将更新 MongoDB 中的现有记录,但我需要将此规范化功能添加到现有的保存和更新代码中。

那么,在 Scala 中是否有任何不错的快捷方式可以将“钩子”添加到案例类的某个字段?例如,在 Java 中可以修改电话号码的设置器。

编辑:

Christian's answer中的解决方案单独工作正常,但在我的情况下,我有字段的默认值(我认为是因为Salat ...)

case class Person(name: String = "a", phone: Option[String] = None, normalizedPhone: Option[String] = None)

object Person {
  def apply(name: String, phone: Option[String]): Person = Person(name, phone, Some("xxx" + phone.getOrElse("")))
}

如果使用类似的东西: Person(phone = Some("s"))

我去拿:Person = Person(a,Some(s),None)

4

3 回答 3

9

你可以在伴生对象中定义一个 apply 方法:

case class Person(name: String, phone: String, normalizedPhone: String)

object Person {
  def apply(name: String, phone: String): Person =  Person(name, phone, "xxx" + phone)
}

然后,在 repl 中:

scala> Person("name", "phone")
res3: Person = Person(name,phone,xxxphone)
于 2014-06-13T09:10:03.850 回答
3

您可以将方法添加到包含现有字段的转换逻辑的案例类。例如:

case class Person(name: String, phone: String) {
  def normalizedPhone = "+40" + phone
}

然后您可以像使用字段一样使用该方法:

val p1 = new Person("Joe", "7234")
println(p1.normalizedPhone) // +407234
于 2014-06-13T07:25:04.360 回答
0

我认为这接近你所需要的。由于无法覆盖生成的 mutator,因此在现有字段前加上下划线,使其私有,然后为原始字段名称编写访问器和 mutator 方法。之后,您只需要在构造函数中增加一行来适应基于构造函数的字段初始化。

case class Test(private var _phoneNumber: String, var formatted: String = "") {
  phoneNumber_=(_phoneNumber)

  def phoneNumber = _phoneNumber

  def phoneNumber_=(phoneNumber: String) {
    _phoneNumber = phoneNumber
    formatted = "formatted" + phoneNumber
  }
}

object Test {
  def main(args: Array[String]) {
    var t = Test("09048751234")

    println(t.phoneNumber)
    println(t.formatted)

    t.phoneNumber = "08068745963"

    println(t.phoneNumber)
    println(t.formatted)
  }
}
于 2014-06-13T09:20:35.190 回答