Xin lỗi vì tiêu đề khó hiểu - nếu tôi có thể đưa ra một tiêu đề ngắn gọn, tôi sẽ không phải đặt câu hỏi.
Giả sử tôi có một loại danh sách bất biến. Nó có một hoạt động Foo(x)
trả về một danh sách bất biến mới với đối số được chỉ định là phần tử phụ ở cuối. Vì vậy, để xây dựng một danh sách các chuỗi có các giá trị "Xin chào", "bất biến", "thế giới" bạn có thể viết:
var empty = new ImmutableList<string>();
var list1 = empty.Foo("Hello");
var list2 = list1.Foo("immutable");
var list3 = list2.Foo("word");
(Đây là mã C # và tôi quan tâm nhất đến đề xuất C # nếu bạn cảm thấy ngôn ngữ là quan trọng. Về cơ bản, đây không phải là câu hỏi về ngôn ngữ, nhưng thành ngữ của ngôn ngữ có thể quan trọng.)
Điều quan trọng là các danh sách hiện tại không bị thay đổi bởi Foo
- vì vậy empty.Count
vẫn sẽ trả về 0.
Một cách khác (thành ngữ hơn) để đi đến kết quả cuối cùng sẽ là:
var list = new ImmutableList<string>().Foo("Hello")
.Foo("immutable")
.Foo("word");
Câu hỏi của tôi là: tên tốt nhất cho Foo là gì?
EDIT 3 : Như tôi tiết lộ sau này, tên của loại có thể không thực sự ImmutableList<T>
, điều này làm cho vị trí rõ ràng. Thay vào đó hãy tưởng tượng rằng nó TestSuite
và nó bất biến bởi vì toàn bộ khuôn khổ mà nó là một phần của bất biến ...
(Kết thúc chỉnh sửa 3)
Các tùy chọn tôi đã đưa ra cho đến nay:
Add
: phổ biến trong .NET, nhưng ngụ ý đột biến của danh sách gốcCons
: Tôi tin rằng đây là tên bình thường trong các ngôn ngữ chức năng, nhưng vô nghĩa với những người không có kinh nghiệm trong các ngôn ngữ đóPlus
: yêu thích của tôi cho đến nay, nó không ngụ ý đột biến đối với tôi . Rõ ràng điều này cũng được sử dụng trong Haskell nhưng với những kỳ vọng hơi khác nhau (một lập trình viên Haskell có thể mong đợi nó sẽ thêm hai danh sách lại với nhau thay vì thêm một giá trị vào danh sách khác).With
: phù hợp với một số quy ước bất biến khác, nhưng không có cùng "tính bổ sung" với IMO.And
: không mô tả lắm.- Toán tử quá tải cho +: Tôi thực sự không thích điều này nhiều; Tôi thường nghĩ rằng các nhà khai thác chỉ nên được áp dụng cho các loại cấp thấp hơn. Tôi sẵn sàng để được thuyết phục mặc dù!
Các tiêu chí tôi đang sử dụng để lựa chọn là:
- Cung cấp ấn tượng chính xác về kết quả của cuộc gọi phương thức (nghĩa là danh sách ban đầu có phần tử phụ)
- Làm cho nó rõ ràng nhất có thể mà nó không làm thay đổi danh sách hiện có
- Âm thanh hợp lý khi kết nối với nhau như trong ví dụ thứ hai ở trên
Vui lòng hỏi thêm chi tiết nếu tôi không làm cho mình đủ rõ ràng ...
EDIT 1: Dưới đây là lập luận của tôi cho thích Plus
đến Add
. Hãy xem xét hai dòng mã này:
list.Add(foo);
list.Plus(foo);
Theo quan điểm của tôi (và đây là một vấn đề cá nhân) thì cái sau rõ ràng là có lỗi - nó giống như viết "x + 5;" như một tuyên bố trên chính nó. Dòng đầu tiên có vẻ ổn, cho đến khi bạn nhớ rằng nó không thay đổi. Trong thực tế, cách mà toán tử cộng tự nó không làm thay đổi toán hạng của nó là một lý do khác khiến Plus
tôi thích. Không có sự quá tải nhẹ của quá tải toán tử, nó vẫn đưa ra các ý nghĩa tương tự, bao gồm (đối với tôi) không làm thay đổi các toán hạng (hoặc mục tiêu phương thức trong trường hợp này).
EDIT 2: Lý do không thích Thêm.
Nhiều câu trả lời khác nhau có hiệu quả: "Đi với Thêm. Đó là những gì DateTime
, và String
có Replace
các phương pháp, v.v ... điều đó không làm cho tính bất biến trở nên rõ ràng." Tôi đồng ý - có quyền ưu tiên ở đây. Tuy nhiên, tôi đã nhìn thấy rất nhiều người gọi DateTime.Add
hoặc String.Replace
và kỳ vọng đột biến . Có rất nhiều câu hỏi của nhóm tin tức (và có thể là những câu hỏi SO nếu tôi tìm hiểu kỹ) được trả lời bởi "Bạn đang bỏ qua giá trị trả về của String.Replace
; chuỗi là bất biến, một chuỗi mới được trả về."
Bây giờ, tôi nên tiết lộ một sự tinh tế cho câu hỏi - loại có thể không thực sự là một danh sách bất biến, mà là một loại bất biến khác. Cụ thể, tôi đang làm việc trên một khung điểm chuẩn nơi bạn thêm các bài kiểm tra vào một bộ và điều đó tạo ra một bộ mới. Có thể rõ ràng rằng:
var list = new ImmutableList<string>();
list.Add("foo");
là sẽ không đạt được bất cứ điều gì, nhưng nó trở thành một nhiều murkier khi bạn thay đổi nó để:
var suite = new TestSuite<string, int>();
suite.Add(x => x.Length);
Có vẻ như nó sẽ ổn thôi. Trong khi đó, với tôi, làm cho sai lầm rõ ràng hơn:
var suite = new TestSuite<string, int>();
suite.Plus(x => x.Length);
Đó chỉ là cầu xin để được:
var suite = new TestSuite<string, int>().Plus(x => x.Length);
Lý tưởng nhất, tôi muốn người dùng của tôi không phải nói rằng bộ thử nghiệm là bất biến. Tôi muốn họ rơi vào hố thành công. Điều này có thể không thể, nhưng tôi muốn thử.
Tôi xin lỗi vì đã đơn giản hóa quá mức câu hỏi ban đầu bằng cách chỉ nói về một loại danh sách bất biến. Không phải tất cả các bộ sưu tập đều khá tự mô tả như ImmutableList<T>
:)