2011-12-12 20 views
7

Ví dụ: nếu tôi có hai bản ghi khác nhau, nhưng chúng có chung một số trường phổ biến, có cách nào để tạo cả hai bản ghi chia sẻ bản ghi cơ bản chung không? Có vẻ như các giao thức chỉ cho phép khai báo chữ ký của phương thức.Có thể thực hiện kế thừa kiểu dữ liệu trong Clojure không?

+0

Hai thực thể đó chia sẻ một số trường không thực sự là lý do đủ để tạo mối quan hệ thừa kế giữa chúng. Có lẽ cung cấp một số kịch bản sử dụng ví dụ. –

+1

Ví dụ, tôi đang sử dụng các bản ghi để biểu diễn các truy vấn SQL được phân tích cú pháp. Vì vậy, tôi có hồ sơ cho SELECT, UPDATE, INSERT, vv .. Họ chia sẻ một vài thuộc tính phổ biến, chẳng hạn như một 'chuỗi' tài sản. Khi tôi xử lý chúng bằng các hàm đa hình, tôi muốn được đảm bảo rằng tất cả chúng đều có một vài thuộc tính chung. – Chris

+1

Bản ghi chỉ là bản đồ ưa thích, vì vậy tôi không rõ ý nghĩa của việc "đảm bảo tất cả chúng đều có một vài thuộc tính phổ biến". Tại sao bạn không thể gọi '(: string a-record)'? Ngoài ra, tập hợp các khóa mà bản ghi có thể có là một vấn đề khác với hành vi mà loại bê tông có thể diễn tả. Vấn đề thực tế là bạn đang cố gắng giải quyết? –

Trả lời

3

Tôi không nghĩ điều đó có thể thực hiện từ bây giờ.

defrecord chỉ là một vĩ mô và bạn có thể kiểm tra những gì nó làm bằng cách sử dụng macroexpand, một cái gì đó như:

(macroexpand '(defrecord User [Name Age])) 

Vì vậy, nếu bạn muốn thừa kế kỷ lục như vậy, bạn có thể cần phải thực hiện một macro để làm như vậy. Nhưng tôi sẽ không gợi ý rằng sự thừa kế là thứ mà tôi cố gắng tránh vì nó dẫn đến sự phức tạp.

3

Bạn nên lập trình dựa trên một trường trừu tượng, không phải là các trường cụ thể, tức là sử dụng giao thức để các bản ghi có thể chia sẻ một giao diện chung. Ví dụ: nếu tất cả các loại bản ghi của bạn cần phải trả lại thuộc tính 'chuỗi', thì hãy tạo giao thức bằng phương thức 'get-string' và mở rộng đó cho từng loại bản ghi.

(defprotocol SQL 
    (get-string [t])) 

(defrecord Thing [name f1 f2] 
    SQL 
    (get-string [t] (str name))) 

(defrecord AnotherThing [name f1 f2 f3 f4 blah] 
    SQL 
    (get-string [t] (str name))) 

Nếu bạn thấy mình đang thực hiện cùng một phương thức giao thức cụ thể, bạn luôn có thể thực hiện và sử dụng nó như thực hiện trong từng loại bản ghi.

+1

Nếu tôi muốn tạo bản ghi chia sẻ một số trường của bản ghi khác thì sao? như: (defrecord a [ba bc]) (defrecord b [ba bc bd] .. làm thế nào để đối phó với trường hợp như vậy? –

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