Значение поля, сгенерированное классом case Scala

#mongodb #scala #scala-2.9

#mongodb #scala #scala-2.9

Вопрос:

У меня есть существующее приложение Scala, и оно использует классы case, которые затем сохраняются в MongoDB. Мне нужно ввести новое поле в класс case, но его значение является производным от существующего поля.

Например, есть номер телефона, и я хочу добавить нормализованный номер телефона, сохранив исходный номер телефона. Я обновлю существующие записи в MongoDB, но мне нужно будет добавить эту функцию нормализации в существующий код сохранения и обновления.

Итак, есть ли в Scala какой-нибудь удобный ярлык для добавления «привязки» к определенному полю класса case? Например, в 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)

Ответ №1:

Вы можете определить метод 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
  

Комментарии:

1. В моем случае я думаю, что мне нужно иметь его как отдельное поле, чтобы сохранить его в MongoDB.

2. Но зачем сохранять его, если оно всегда является производным от другого поля? Разве это не было бы избыточностью?

3. Оно должно быть в БД, чтобы его можно было быстро индексировать и запрашивать. Запрос регулярных выражений MongoDB был недостаточно быстрым.

Ответ №3:

Я думаю, что это близко к тому, что вам нужно. Поскольку вы не можете переопределить сгенерированный мутатор, добавьте к существующему полю префикс подчеркивания, сделайте его закрытым, а затем напишите методы доступа и мутатора для исходного имени поля. После этого вам понадобится только дополнительная строка в конструкторе для размещения инициализации поля на основе конструктора.

 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)
  }
}