Đối tượng bất biến so với Bộ sưu tập bất biến
Một trong những điểm tốt hơn trong cuộc tranh luận về các đối tượng có thể thay đổi và bất biến là khả năng mở rộng khái niệm bất biến cho các bộ sưu tập. Một đối tượng bất biến là một đối tượng thường đại diện cho một cấu trúc logic duy nhất của dữ liệu (ví dụ: một chuỗi bất biến). Khi bạn có một tham chiếu đến một đối tượng bất biến, nội dung của đối tượng sẽ không thay đổi.
Một bộ sưu tập bất biến là một bộ sưu tập không bao giờ thay đổi.
Khi tôi thực hiện một thao tác trên một bộ sưu tập có thể thay đổi, sau đó tôi thay đổi bộ sưu tập tại chỗ và tất cả các thực thể có tham chiếu đến bộ sưu tập sẽ thấy sự thay đổi.
Khi tôi thực hiện một thao tác trên một bộ sưu tập bất biến, một tham chiếu được trả về một bộ sưu tập mới phản ánh sự thay đổi. Tất cả các thực thể có tham chiếu đến các phiên bản trước của bộ sưu tập sẽ không thấy sự thay đổi.
Việc triển khai thông minh không nhất thiết phải sao chép (sao chép) toàn bộ bộ sưu tập để cung cấp sự bất biến đó. Ví dụ đơn giản nhất là ngăn xếp được triển khai như một danh sách liên kết đơn và các hoạt động đẩy / pop. Bạn có thể sử dụng lại tất cả các nút từ bộ sưu tập trước trong bộ sưu tập mới, chỉ thêm một nút duy nhất cho việc đẩy và nhân bản không có nút nào cho cửa sổ bật lên. Hoạt động Push_tail trên một danh sách liên kết đơn, mặt khác, không đơn giản hoặc hiệu quả.
Các biến / tham chiếu không thay đổi so với Mutable
Một số ngôn ngữ chức năng lấy khái niệm bất biến cho chính các tham chiếu đối tượng, chỉ cho phép một phép gán tham chiếu duy nhất.
- Trong Erlang, điều này đúng với tất cả các "biến". Tôi chỉ có thể gán các đối tượng cho một tham chiếu một lần. Nếu tôi vận hành trên một bộ sưu tập, tôi sẽ không thể gán lại bộ sưu tập mới cho tham chiếu cũ (tên biến).
- Scala cũng xây dựng ngôn ngữ này với ngôn ngữ với tất cả các tham chiếu được khai báo bằng var hoặc val , vals chỉ là một phép gán duy nhất và quảng bá một kiểu chức năng, nhưng các vars cho phép cấu trúc chương trình giống như C hoặc Java hơn.
- Khai báo var / val là bắt buộc, trong khi nhiều ngôn ngữ truyền thống sử dụng các sửa đổi tùy chọn như cuối cùng trong java và const trong C.
Dễ phát triển so với hiệu suất
Hầu như luôn luôn lý do để sử dụng một đối tượng bất biến là để thúc đẩy lập trình miễn phí hiệu ứng phụ và lý luận đơn giản về mã (đặc biệt là trong môi trường song song / đồng thời cao). Bạn không phải lo lắng về việc dữ liệu cơ bản bị thay đổi bởi một thực thể khác nếu đối tượng là bất biến.
Hạn chế chính là hiệu suất. Dưới đây là một bài viết về một bài kiểm tra đơn giản mà tôi đã làm trong Java so sánh một số vật thể bất biến và có thể thay đổi trong một vấn đề đồ chơi.
Các vấn đề về hiệu năng có rất nhiều trong các ứng dụng, nhưng không phải tất cả, đó là lý do tại sao nhiều gói số lớn, chẳng hạn như lớp Numpy Array trong Python, cho phép cập nhật tại chỗ các mảng lớn. Điều này sẽ rất quan trọng đối với các khu vực ứng dụng sử dụng các phép toán ma trận và vectơ lớn. Vấn đề lớn song song dữ liệu lớn và tính toán này đạt được tốc độ lớn bằng cách vận hành tại chỗ.
string
là bất biến, ít nhất là trong .NET, và tôi nghĩ trong nhiều ngôn ngữ hiện đại khác cũng vậy.