我有一个现有的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)
答案 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)
}
}