2009-06-03 64 views

Trả lời

28

Tôi không đặc biệt thích câu trả lời tôi đã nhập dưới đây, bởi vì tôi nghĩ người đọc sẽ xem nó như là 'rao giảng cho ca đoàn' hoặc là 'một số điều vô nghĩa phức tạp', nhưng tôi đã quyết định đăng nó anyway, trong trường hợp nó mời bình luận thảo luận hiệu quả.

Trước hết, nó có thể là đáng chú ý để hiểu rằng

let x : string option = Some(null) 

là một giá trị hợp lệ, cho biết sự hiện diện (chứ không phải là sự vắng mặt) của một giá trị (Một số chứ không phải là None), nhưng giá trị chính nó là vô giá trị. (Ý nghĩa của một giá trị như vậy sẽ phụ thuộc vào ngữ cảnh.)

Nếu bạn đang tìm kiếm những gì tôi nhìn thấy là mô hình về tinh thần 'đúng', nó đi một cái gì đó như thế này ...

Toàn bộ quan điểm cho rằng "tất cả các loại tham chiếu thừa nhận một giá trị 'null'" là một trong những sai lầm lớn nhất và tốn kém nhất của .Net và CLR. Nếu nền tảng được thiết kế lại từ đầu ngày hôm nay, tôi nghĩ hầu hết mọi người đều đồng ý rằng các tham chiếu sẽ không có giá trị mặc định, và bạn sẽ cần một cơ chế rõ ràng để chọn tham gia null. Như hiện nay, có hàng trăm, nếu không phải hàng nghìn API, ví dụ: "string foo" và không muốn null (ví dụ: sẽ ném ArgumentNullException nếu bạn đã bỏ qua null). Rõ ràng đây là một cái gì đó xử lý tốt hơn bởi một hệ thống kiểu. Lý tưởng nhất, 'chuỗi' có nghĩa là 'không rỗng' và đối với số của các API do muốn null, bạn đánh vần ra, ví dụ: "Nullable < string> foo" hoặc "Tùy chọn < chuỗi> foo" hoặc bất kỳ thứ gì. Vì vậy, đó là nền tảng .Net hiện tại là 'kỳ quặc' ở đây.

Nhiều ngôn ngữ chức năng (như ML, một trong những ảnh hưởng chính của F #) đã biết điều này mãi mãi, và do đó thiết kế hệ thống kiểu của họ 'phải', nếu bạn muốn thừa nhận giá trị 'null', bạn sử dụng phương thức khởi tạo kiểu generic để báo hiệu rõ ràng dữ liệu cố tình có thể có 'giá trị của một giá trị' như một giá trị pháp lý. Trong ML, điều này được thực hiện với tùy chọn "'t option" -' option 'là một giải pháp tốt, có mục đích chung cho vấn đề này. F # của lõi là tương thích (cross-biên dịch) với OCaml, một phương ngữ ML, và do đó F # kế thừa loại này từ tổ tiên ML của nó.

Nhưng F # cũng cần tích hợp với CLR và trong CLR, tất cả các tham chiếu có thể là rỗng.F # cố gắng đi bộ một dòng hơi tốt, trong đó bạn có thể xác định các loại lớp mới trong F #, và đối với những chủng loại, F # sẽ cư xử ML-tương tự (và không dễ dàng thừa nhận null như một giá trị):

type MyClass() = class end 
let mc : MyClass = null // does not compile 

tuy nhiên cùng một loại được định nghĩa trong một assembly C# sẽ thừa nhận null như một giá trị thích hợp trong F #. (Và F # vẫn cho phép một back-door:.

let mc : MyClass = Unchecked.defaultof<_> // mc is null 

để có hiệu quả có được xung quanh hệ thống F # loại bình thường và truy cập vào CLR trực tiếp)

này là tất cả bắt đầu âm thanh phức tạp, nhưng về cơ bản # hệ thống F cho phép bạn khá nhiều chương trình của F # trong phong cách 'ML', nơi bạn không bao giờ cần phải lo lắng về null/NullReferenceExceptions, bởi vì hệ thống kiểu ngăn bạn làm những điều sai ở đây. Nhưng F # phải tích hợp độc đáo với .Net, vì vậy tất cả các kiểu bắt nguồn từ mã không phải F # (như 'string') vẫn thừa nhận giá trị null, và vì vậy khi lập trình với các kiểu đó, bạn vẫn phải lập trình phòng thủ như thường lệ CLR. Liên quan đến null, hiệu quả F # cung cấp một thiên đường, nơi nó rất dễ dàng để làm 'lập trình mà không có null, cách Chúa dự định', nhưng đồng thời tương thích với phần còn lại của. Net.

Tôi chưa thực sự trả lời câu hỏi của bạn, nhưng nếu bạn làm theo logic của tôi, thì bạn sẽ không hỏi câu hỏi (hoặc sẽ giải thích nó, MU của Joshu từ "Godel, Escher, Bach").

+1

Nó không phải theo cách này. Chúng có thể có các hàm CLR được ánh xạ tới "tùy chọn " thay vì "Chuỗi" trừ khi chúng được đánh dấu là không bao giờ trả lại giá trị rỗng. Và trong .NET 4, các hàm được cho là được đánh dấu như vậy. –

+0

Tôi thích câu trả lời này, rất nhiều giá trị gia tăng cho StackOverflow. – Benjol

+1

Nếu chỉ có tôi mới có thể 'yêu thích' câu trả lời. Ah tốt. Anywho, nếu họ làm thế, Grauren, chúng ta sẽ có một cơn ác mộng về một mẫu thời gian phù hợp với mọi 'lựa chọn' mà khuôn khổ phun ra. Rất may, không có nhiều chức năng có thể trả về giá trị rỗng, vì vậy bạn không phải quá thận trọng. – YotaXP

4

Tôi nghĩ bạn có thể phân loại lại này như một câu hỏi tổng quát hơn

sự khác biệt giữa các tùy chọn loại ref ngẫu nhiên và chỉ cần một loại ref ngẫu nhiên là gì

Sự khác biệt là với một lựa chọn, bạn đang cung cấp một trường hợp giá trị rỗng trống. Đó là một cách khai báo để nói "Tôi có thể không cung cấp một giá trị". Một tùy chọn giá trị Không rõ ràng đại diện cho việc thiếu một giá trị.

Thông thường, mọi người sử dụng null để thể hiện sự thiếu giá trị. Thật không may điều này là mơ hồ đối với người đọc bình thường vì nó không rõ nếu null đại diện cho một giá trị hợp lệ hoặc thiếu một giá trị. Tùy chọn loại bỏ sự mơ hồ này.

+0

Làm cách nào để xóa sự mơ hồ? Từ nơi tôi đang ngồi ở đó là không có sự khác biệt giữa ràng buộc một null với một biến và ràng buộc một không với một biến. –

+0

@Grauenwolf vấn đề là null thường là giá trị không trống hợp lệ. Tùy chọn mặc dù có nghĩa là một "tôi không có giá trị" rõ ràng. Tôi nghĩ rằng cách tốt nhất để hiểu sự khác biệt là xem xét rằng nó có thể có một tùy chọn với một giá trị Một số null. – JaredPar

+0

Vì vậy, bây giờ chúng ta có thể kiểm tra cả hai null-style nulls và null-style nulls? Đây không phải là niềm vui. –

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