2012-01-20 48 views
17

Lý do F # không hỗ trợ các lớp lồng nhau kỹ thuật, phong cách, tùy ý?Tại sao F # không hỗ trợ các lớp lồng nhau?

Liếc qua BCL trong Trình phản xạ, các lớp lồng nhau được sử dụng cho các điều tra viên, DynamicMetaObject và có thể là một vài thứ khác.

Điều đó đã khơi dậy sự tò mò của tôi về F # không có tính năng này. Tôi biết rằng có nhiều cách khác để làm điều tương tự. Tôi hầu như tò mò.

+6

Nó hỗ trợ lớp lồng nhau (tĩnh): 'module X = module Y = let j = 3 ;;' –

Trả lời

19

Tôi cho rằng các lớp lồng nhau không phải là tính năng cốt lõi của mô hình đối tượng .NET và nó chỉ đơn giản là bị loại bỏ để lưu tài nguyên. Có thể có một số khó khăn về kỹ thuật (tức là với khả năng hiển thị hoặc với định nghĩa kiểu đệ quy), nhưng tôi không nghĩ đó sẽ là một vấn đề lớn.

Đối với nhiều trường hợp người ta sẽ sử dụng lớp lồng nhau trong C#, chẳng hạn như vòng lặp, bạn độc đáo có thể sử dụng các biểu tượng, vì vậy tôi đoán họ đang có trong một số thay thế cách cho các lớp lồng nhau:

type Collection() = 
    member x.GetEnumerator() = 
    let n = ref 0 
    { new IEnumerator with 
     member x.Current = box n.Value 
     member x.MoveNext() = incr n; true 
     member x.Reset() = n := 0 } 

Mặc dù đây là khá giống với các lớp lồng nhau, nó không được biên dịch như lớp lồng nhau và phần thân của biểu thức đối tượng không thể truy cập các thành viên riêng của Collection. Tôi đoán hỗ trợ điều này sẽ phức tạp biên dịch các biểu thức một chút, bởi vì các biểu thức đối tượng có thể xuất hiện bên ngoài một bối cảnh lớp học ...

Thực tế, có thể truy cập private thành viên từ biểu thức đối tượng, mặc dù mã vẫn không được biên dịch thành một lớp lồng nhau. Xem nhận xét để biết chi tiết.

+1

Một sửa lỗi nhỏ: nó có thể tham chiếu đến 'các ràng buộc 'cho phép/các thành viên riêng của kiểu kèm theo từ một biểu thức đối tượng. Điều này, theo quan điểm của tôi, làm cho chúng trở thành một giải pháp tốt hơn so với các lớp lồng nhau. – Daniel

+1

@Daniel Bạn nói đúng - bạn có thể truy cập các thành viên riêng tư (tôi đã gặp lỗi trong bài kiểm tra của mình). Thật thú vị, khi bạn làm điều đó, thành viên bạn đang truy cập được inline hoặc biên dịch là 'internal' để làm cho truy cập này an toàn (nhưng trình biên dịch F # coi nó là' private'). –

+3

@Tomas: Thực ra, theo đặc điểm kỹ thuật F #, "Mẫu CLI được biên dịch của các thực thể ngoài công lập _all_ là nội bộ". ... đó là lý do tại sao người ta không nên cung cấp cho khách hàng không phải F # đặc quyền [] ... họ sẽ thấy mọi thứ là _private_ trong hội đồng F # như _internal_! –

2

F # chủ yếu dựa trên Caml, không có lớp lồng nhau.

Nó có thể không được thêm vào đơn giản bởi vì nó không phải là ưu tiên rất cao. Vì bạn có thể khai báo các kiểu dữ liệu không hiển thị bên ngoài một mô-đun, cho phép các lớp bên trong sẽ không tạo ra nhiều sự khác biệt trong việc mã hóa được mã của bạn.

+10

Điều đó rất có thể không phải là trường hợp - mặc dù F # phần lớn dựa trên OCaml, mô hình đối tượng được sử dụng trong F # dựa trên .NET nhiều hơn trên OCaml. –

+0

+1 để đề cập rằng chúng không cần thiết vì bạn có thể sử dụng tệp chữ ký để ẩn chúng. – YellPika

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