Скажем, у меня есть класс case, который представляет персонажи, людей в разных социальных сетях. Экземпляры этого класса полностью неизменяемы и хранятся в неизменных коллекциях, которые в конечном итоге будут изменены аккой Аккой.
Теперь у меня есть класс case со многими полями, и я получаю сообщение, в котором говорится, что я должен обновить одно из полей, примерно так:
case class Persona(serviceName : String,
serviceId : String,
sentMessages : Set[String])
// Somewhere deep in an actor
val newPersona = Persona(existingPersona.serviceName,
existingPersona.serviceId,
existingPersona.sentMessages + newMessage)
Заметьте, что я должен указать все поля, хотя только один изменяется. Есть ли способ клонировать existingPersona и заменять только одно поле без указания всех полей, которые не изменяются? Могу ли я написать это как свойство и использовать его для всех классов классов?
Если Persona был экземпляром, похожим на карту, это было бы легко сделать.
case class
поставляется с методом copy
, который предназначен именно для этого использования:
val newPersona = existingPersona.copy(sentMessages =
existingPersona.sentMessages + newMessage)
Начиная с 2.8, Scala классы case имеют метод copy
, который использует свойства named/default для работы своей магией:
val newPersona =
existingPersona.copy(sentMessages = existing.sentMessages + newMessage)
Вы также можете создать метод на Persona
, чтобы упростить использование:
case class Persona(
svcName : String,
svcId : String,
sentMsgs : Set[String]
) {
def plusMsg(msg: String) = this.copy(sentMsgs = this.sentMsgs + msg)
}
затем
val newPersona = existingPersona plusMsg newMsg
existingPersona.copy(sentMessages = existingPersona.sentMessages + newMessage)