Scala案例类生成的字段值

时间:2014-06-13 07:02:37

标签: mongodb scala scala-2.9

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

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

那么,Scala中是否有一个很好的快捷方式来添加" hook"到一个案例类的某个领域?例如,在Java中,可以修改电话号码的设置者。

编辑:

克里斯蒂安答案中的解决办法很好,但在我的情况下,我有字段的默认值(我认为因为萨拉特...)

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)

3 个答案:

答案 0 :(得分:7)

您可以在随播对象中定义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)

答案 1 :(得分:2)

您可以向case类添加方法,这些方法将包含现有字段中的转换逻辑。例如:

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

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

val p1 = new Person("Joe", "7234")
println(p1.normalizedPhone) // +407234

答案 2 :(得分:0)

我认为这接近你所需要的。由于您无法覆盖生成的mutator,请在现有字段前加下划线,将其设为私有,然后为原始字段名称编写accessor和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)
  }
}