Câu hỏi Làm thế nào để sao chép một cá thể lớp vỏ và thay đổi chỉ một trường trong Scala?


Hãy nói rằng tôi có một lớp trường hợp đại diện cho personas, mọi người trên các mạng xã hội khác nhau. Các cá thể của lớp đó hoàn toàn bất biến và được tổ chức trong các bộ sưu tập bất biến, cuối cùng được sửa đổi bởi một diễn viên Akka.

Bây giờ, tôi có một trường hợp lớp với nhiều lĩnh vực, và tôi nhận được một thông báo nói rằng tôi phải cập nhật một trong các lĩnh vực, một cái gì đó như thế này:

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)

Lưu ý rằng tôi phải chỉ định tất cả các trường, mặc dù chỉ có một thay đổi. Có cách nào để sao chép hiện tạiPersona và chỉ thay thế một trường, mà không chỉ định tất cả các trường không thay đổi? Tôi có thể viết đó như một đặc điểm và sử dụng nó cho tất cả các trường hợp của tôi không?

Nếu Persona là một phiên bản giống như Map, nó sẽ dễ thực hiện.


179
2017-08-30 20:28


gốc




Các câu trả lời:


case classđi kèm với một copy phương pháp được dành riêng cho việc sử dụng này:

val newPersona = existingPersona.copy(sentMessages = 
                   existingPersona.sentMessages + newMessage)

274
2017-08-30 20:32



Tài liệu đó ở đâu? Tôi không thể tìm thấy tham chiếu để sao chép ở các vị trí "hiển nhiên", scala-lang.org/api/current/index.html ví dụ. - François Beausoleil
Đó là một tính năng của ngôn ngữ, bạn có thể tìm thấy nó trong đặc tả Scala: scala-lang.org/docu/files/ScalaReference.pdf §5.3.2. Nó không có trong API vì nó không phải là một phần của API;) - Nicolas
Tôi dự định làm cho ScalaDoc hiển thị các phương thức sao chép khi chúng tồn tại, không phải là những gì bạn muốn? - soc
Nó sẽ rất tuyệt. Nhưng ở đây, vấn đề của François (nếu tôi đúng) là anh ta không biết rằng anh ta sẽ có một copy phương pháp nếu anh ta tuyên bố case class. - Nicolas
Làm thế nào để bạn nuôi một con hà mã bằng Scala? bạn tạo ra một bản sao với các thực phẩm đã có trong dạ dày của mình sau đó chờ đợi quản lý chất thải để đi yêu cầu bồi thường một trong những đói. Đây là một trong những điều kỳ quặc khi làm việc với các kiểu dữ liệu bất biến làm tôi bực bội và không tự động giải quyết các vấn đề với tính song song, hoặc chỉ giới thiệu những thứ khác nhau. - Jonathan Neufeld


Kể từ 2.8, các trường hợp Scala có một copy phương pháp tận dụng các tham số được đặt tên / mặc định để thực hiện phép thuật của nó:

val newPersona =
  existingPersona.copy(sentMessages = existing.sentMessages + newMessage)

Bạn cũng có thể tạo phương thức Persona để đơn giản hóa việc sử dụng:

case class Persona(
  svcName  : String,
  svcId    : String,
  sentMsgs : Set[String]
) {
  def plusMsg(msg: String) = this.copy(sentMsgs = this.sentMsgs + msg)
}

sau đó

val newPersona = existingPersona plusMsg newMsg

41
2017-08-30 20:34





existingPersona.copy(sentMessages = existingPersona.sentMessages + newMessage)

9
2017-08-30 20:32