2011-07-12 18 views
15

Trong Thủy Tôi có thể sử dụng:Scala có cú pháp cập nhật bản ghi để tạo bản sao sửa đổi cấu trúc dữ liệu không thay đổi được không?

A = B^some_field := SomeValue 

để ràng buộc A đến một bản sao của B, ngoại trừ việc some_fieldSomeValue thay vì bất cứ điều gì nó được trong B. Tôi tin rằng Haskell tương đương là một cái gì đó như:

a = b { some_field = some_value } 

Scala có một cái gì đó như thế này cho "sửa đổi" giá trị bất biến. Phương án thay thế có vẻ là có một hàm tạo trực tiếp thiết lập mọi trường trong cá thể, mà không phải lúc nào cũng lý tưởng (nếu có các trình invarients mà constructor cần duy trì). Cộng với nó sẽ thực sự clunky và mong manh hơn nhiều nếu tôi đã phải rõ ràng vượt qua mọi giá trị khác trong trường hợp tôi muốn có một bản sao sửa đổi.

Tôi không thể tìm thấy gì về điều này bằng cách googling hoặc trong một cuộc khảo sát ngắn gọn về hướng dẫn tham khảo ngôn ngữ hoặc "Scala By Example" (mà tôi đã đọc bắt đầu để hoàn thành, nhưng chưa hấp thụ hết , vì vậy nó cũng có thể ở trong đó).

tôi có thể thấy rằng tính năng này có thể có một số tương tác lạ với bảo vệ truy cập Java-phong cách và lớp con dù ...

+1

Lớp học không phải là những gì bạn đang tìm kiếm? http://daily-scala.blogspot.com/2010/01/case-classes-in-28.html –

+0

Xem thêm http://stackoverflow.com/questions/3900307/cleaner-way-to-update-nested- cấu trúc –

Trả lời

11

Bạn có thể sử dụng các lớp chữ hoa chữ thường, nhưng bạn không phải làm như vậy. Trường hợp các lớp học là không có gì huyền diệu - sửa đổi case chỉ giúp bạn tiết kiệm rất nhiều đánh máy. Phương thức sao chép được thực hiện bằng cách sử dụng các tham số được đặt tên và mặc định. Các tên giống với các trường và giá trị mặc định là các giá trị hiện tại của các trường. Dưới đây là ví dụ:

class ClassWithCopy(val field1:String, val field2:Int) { 
    def copy(field1:String = this.field1, field2:Int = this.field2) = { 
     new ClassWithCopy(field1,field2); 
    } 
} 

Bạn có thể sử dụng phương pháp này giống như phương pháp sao chép trên các kiểu chữ thường. Các tham số được đặt tên và mặc định là một tính năng rất hữu ích và không chỉ cho các phương thức sao chép.

+2

Wow, làm thế nào tôi nhớ rằng Scala đã đặt tên là thông số đi qua? Điều đó sẽ rất hữu ích. Tôi chấp nhận câu trả lời này, vì nó giải thích cách thức sao chép trên các lớp case hoạt động, cũng như cách tôi có thể áp dụng các ý tưởng ngay cả khi các trường hợp không thích hợp. – Ben

4

Nếu đối tượng bạn đang lập kế hoạch về sửa đổi là một lớp hợp sau đó bạn có thể sử dụng được tạo tự động phương pháp sao chép:

scala> val user = User(2, "Sen") 
user: User = User(2,Sen) 

scala> val corrected = user.copy(name = "Sean") 
corrected: User = User(2,Sean) 
26

Nếu bạn xác định lớp học của bạn như một case class, một phương pháp thuận tiện copy được tạo ra, và gọi đó là bạn có thể chỉ định với tên thông số giá trị mới cho các lĩnh vực nhất định.

scala> case class Sample(str: String, int: Int) 
defined class Sample 

scala> val s = Sample("text", 42) 
s: Sample = Sample(text,42) 

scala> val s2 = s.copy(str = "newText") 
s2: Sample = Sample(newText,42) 

Nó thậm chí làm việc với các lớp học trường hợp đa hình:

scala> case class Sample[T](t: T, int: Int) 
defined class Sample 

scala> val s = Sample("text", 42) 
s: Sample[java.lang.String] = Sample(text,42) 

scala> val s2 = s.copy(t = List(1,2,3), 42) 
s2: Sample[List[Int]] = Sample(List(1, 2, 3),42) 

Lưu ý rằng s2 có một loại khác với s.

+0

Cảm ơn rất nhiều vì đã chỉnh sửa, Lukas, tôi vừa học được điều gì đó mới mẻ! –

+0

Cảm ơn các ví dụ tuyệt vời! Bản sao đa hình rất tiện lợi. – Ben

Các vấn đề liên quan