2010-06-24 28 views
14

Tôi đang phát triển một cấu trúc dữ liệu phức tạp trong Clojure với nhiều cấu trúc phụ.Tóm tắt các chi tiết triển khai cấu trúc dữ liệu trong Clojure

Tôi biết rằng tôi sẽ muốn mở rộng cấu trúc này theo thời gian và đôi khi muốn thay đổi cấu trúc bên trong mà không phá vỡ cấu trúc dữ liệu khác nhau (ví dụ: tôi có thể muốn thay đổi vectơ thành băm một số loại cấu trúc chỉ mục vì lý do hiệu suất, hoặc kết hợp một loại Java)

suy nghĩ hiện tại của tôi là:

  • Xác định một giao thức cho các cấu trúc tổng thể với các phương pháp accessor khác nhau
  • Tạo một mini-thư viện các hàm điều hướng cấu trúc dữ liệu e .g. (Query-Hạ tầng cơ sở-abc param1 param2)
  • Thực hiện các cấu trúc dữ liệu sử dụng defrecord hoặc deftype, với các phương pháp giao thức được định nghĩa để sử dụng thư viện mini-

Tôi nghĩ rằng điều này sẽ làm việc, mặc dù tôi lo lắng nó đang bắt đầu trông giống như rất nhiều "keo" mã. Ngoài ra nó cũng có thể phản ánh sự quen thuộc của tôi với các phương pháp hướng đối tượng.

Cách được khuyến nghị để thực hiện điều này trong Clojure là gì?

Trả lời

11

Tôi nghĩ rằng deftype có thể là cách để đi, tuy nhiên tôi muốn có một vượt qua trên các phương pháp accessor. Thay vào đó, hãy xem xét clojure.lang.ILookupclojure.lang.Associative; đây là các giao diện, nếu bạn thực hiện chúng cho loại của bạn, sẽ cho phép bạn sử dụng get/get-inassoc/assoc-in, làm cho một giải pháp linh hoạt hơn nhiều (không chỉ bạn mới có thể thay đổi việc triển khai cơ bản, nhưng cũng có thể sử dụng các hàm được xây dựng trên thư viện bộ sưu tập chuẩn của Clojure để thao tác các cấu trúc của bạn).

Một vài điều cần lưu ý:

  1. Bạn có lẽ nên bắt đầu bằng defrecord, sử dụng get, assoc & Công ty với tiêu chuẩn defrecord hiện thực của ILookup, Associative, IPersistentMapjava.util.Map. Bạn có thể đi một chặng đường khá dài với nó.

    Nếu/khi những điều này không còn đủ, hãy xem các nguồn cho emit-defrecord (một chức năng riêng được xác định trong core_deftype.clj trong các nguồn của Clojure). Nó khá phức tạp, nhưng nó sẽ cung cấp cho bạn một ý tưởng về những gì bạn có thể cần phải thực hiện.

  2. Không deftype cũng không phải defrecord hiện đang xác định bất kỳ chức năng nào của nhà máy cho bạn, nhưng bạn có thể tự làm điều đó. Việc kiểm tra tính thân thiện đi vào bên trong các chức năng đó (và/hoặc các bài kiểm tra tương ứng).

  3. Các hoạt động khái niệm phức tạp hơn là tất nhiên hoàn toàn phù hợp cho các chức năng giao thức được xây dựng trên nền tảng của get & Công ty

Oh, và có một cái nhìn tại gvec.clj trong nguồn Clojure cho một ví dụ về một số mã cấu trúc dữ liệu nghiêm trọng được viết bằng cách sử dụng deftype có thể trông như thế nào.Sự phức tạp ở đây khác với những gì bạn mô tả trong câu hỏi, nhưng vẫn là một trong số ít ví dụ về lập trình cấu trúc dữ liệu tùy chỉnh trong Clojure hiện có sẵn cho tiêu dùng công cộng (và dĩ nhiên nó là mã chất lượng tuyệt vời).

Tất nhiên đây chỉ là những gì trực giác của tôi nói với tôi vào lúc này. Tôi không chắc chắn rằng có rất nhiều trong cách thành lập thành lập ở giai đoạn này, những gì với deftype không thực sự đã được phát hành và tất cả. :-)

+0

Cảm ơn Michal! Insightful như bao giờ :-) chắc chắn sẽ xem xét các tùy chọn ILookup và Associative – mikera

+0

Đây là một câu trả lời rất hữu ích! Nhưng gần ba năm sau nó sẽ rất tuyệt vời để cập nhật điều này (hoặc tạo ra một câu trả lời mới) dựa trên tính năng hiện có sẵn trong 1.5. Một điều tôi nhận thấy là 'defrecord' hiện phát ra các chức năng của nhà máy, không chắc chắn những thay đổi khác có thể ảnh hưởng đến câu trả lời này. –

+0

Tôi nghĩ câu trả lời này cũng có thể sử dụng bản cập nhật - ngay cả cuốn sách của O'Reily Clojure cũng cho biết rằng tính năng defrecord của clojure tạo ra các chức năng của nhà máy. – djhaskin987

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