2011-01-10 30 views

Trả lời

5

tôi đã kết thúc với việc thực hiện sau đây:

(defn protocol? [maybe-p] 
    (boolean (:on-interface maybe-p))) 

(defn all-protocols [] 
    (filter #(protocol? @(val %)) (ns-publics *ns*))) 

(defn implemented-protocols [sym] 
    (filter #(satisfies? @(val %) sym) (all-protocols))) 

Đầu tiên nó sẽ tìm kiếm tất cả những biểu tượng trong không gian tên hiện tại (bạn có thể tất nhiên mở rộng này cho tất cả các không gian tên) cho dù họ là định nghĩa giao thức hoặc ròng (tất cả -giao thức). Tiếp theo nó sẽ tìm một biểu tượng cho sẵn nếu nó đáp ứng một trong các giao thức này.

Giao thức? chức năng sử dụng phím: trên giao diện không được ghi lại, vì vậy chức năng này không thể di chuyển được.

+0

'giao thức?' Thất bại trên một bản đồ được sắp xếp, ít nhất là trong Clojure 1.8. Xem [câu hỏi này] (http://stackoverflow.com/q/37410580/1393162). –

0

Tôi thực sự không thể thử điều này vào lúc này, nhưng bạn có thể muốn thử phương thức lớp Java: getGenericInterfaces. Điều này sẽ cung cấp cho bạn một danh sách các giao diện. Có lẽ những cách khác để có được thông tin này bằng cách sử dụng các phương pháp tương tự nhưng tôi đã không nhìn.

Nếu bạn cũng xem mã nguồn, bạn sẽ thấy cách thức giao thức được thiết lập (bạn có thể truy cập nguồn bằng cách nhấp vào liên kết trong api clojure). Trong Clojure 1.3 có một chức năng 'tư nhân' trông như thế này:

(defn- protocol? 
    [maybe-p] 
    (boolean (:on-interface maybe-p))) 

Chức năng này được sử dụng bởi extend chức năng Clojure để kiểm tra xem bạn đã thực sự cung cấp một giao thức. Nếu bạn thực hiện chức năng của riêng mình như vậy, bạn có thể lọc kết quả của getGenericInterfaces. Vì đây là chi tiết nội bộ nên có thể thay đổi.

+0

getGenericInterfaces cung cấp cho tôi (clojure.lang.IObj clojure.lang.ILookup clojure.lang.IKeywordLookup clojure.lang.IPersistentMap java.util.Map java.io.Serializable) nhưng không phải là giao thức được triển khai. Tôi đoán tôi sẽ phải nghiên cứu mã nguồn để xem nó được thực hiện như thế nào. –

+0

Chỉ cần quay trở lại máy của tôi, và tôi không nhận được bất kỳ xa hơn bạn đang có. Nó có thể đơn giản hơn để sử dụng 'getInterfaces' như là một lựa chọn hợp lý cho' getGenericInterfaces'. Tôi tự hỏi điều gì sẽ xảy ra nếu bạn AOT biên dịch điều này. – hutch

+2

Một phần của giao thức là một lớp không cần phải thực hiện một giao diện để mở rộng một giao thức: bạn có thể định nghĩa giao thức của riêng mình và sau đó nói rằng một số lớp đã tồn tại mở rộng nó với '(extend ExistingClass MyProtocol ...)'. Do đó, tự nhiên có cách để hỏi "những lớp nào mở rộng giao thức này" nhưng không phải là cách để hỏi câu hỏi ngược. –

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