2015-08-28 14 views
9

tôi tò mò tại sao các công trình này (như tôi mong chờ nó sau khi đọc the documentation on the dot special form):Clojure của dot dạng đặc biệt weirdness

(map #(. % isInstance {}) [clojure.lang.IPersistentMap]) 

lợi nhuận:

(true) 

Nhưng điều này không:

(. clojure.lang.IPersistentMap isInstance {}) 

Tôi gặp lỗi "Không có phương thức khớp: isInstance". Biểu mẫu chính xác giống như trong cuộc gọi hàm map ở trên, nhưng bên ngoài map, biểu mẫu không hoạt động. Tại sao?

Trả lời

6

Hình thức sperial . (chấm) là kỳ lạ nhất trong số tất cả. Không chắc tôi sẽ giải thích rõ, nhưng hãy thử đi.

mỗi docs:

Nếu toán hạng đầu tiên là một biểu tượng mà giải quyết để một tên lớp, việc tiếp cận được coi là một thành viên tĩnh của lớp được đặt tên. Lưu ý rằng các lớp lồng nhau được đặt tên là EnclosingClass $ NestedClass, theo thông số JVM. Nếu không, nó được coi là một thành viên thể hiện và đối số đầu tiên được đánh giá để tạo ra đối tượng đích.

Mỏ nhấn mạnh.

Vì vậy, bạn đã nhấn trường hợp đầu tiên với (. clojure.lang.IPersistentMap isInstance {}) - clojure.lang.IPersistentMap giải quyết tên lớp và toàn bộ biểu thức được giả định là cuộc gọi phương thức tĩnh.

Trong trường hợp map trường hợp biểu tượng được đánh giá (phần được nhấn mạnh), đánh giá đối tượng lớp clojure.lang.IPersistentMap trước khi được chuyển tới hàm ẩn danh và toàn bộ biểu thức là cuộc gọi phương thức thể hiện trên lớp đó.

Vì vậy, nó sẽ tập trung vào thực tế ở một nơi mà clojure.lang.IPersistentMap đang được sử dụng làm biểu tượng đề cập đến tên lớp và mặt khác như một thứ đánh giá đối tượng lớp.

Ngoài ra nhìn here:

Lưu ý rằng tên lớp thường biểu thị các đối tượng lớp, nhưng được đối xử đặc biệt trong một số hình thức đặc biệt, ví dụ '.' và mới.

+3

Giải thích này là chính xác Tôi chỉ thêm rằng bạn có thể buộc trình biên dịch xem xét đối tượng lớp bằng cách thực hiện '(. (Do clojure.lang.IPersistentMap) isInstance {})' (trong số các cách khác). Tuy nhiên, biểu mẫu đặc biệt '.' (và' mới' quá) là rất thấp và trừ khi bạn đang viết một số macro interop, bạn không nên sử dụng nó. Hãy ưu tiên '.member',' constructor.' và 'Class/staticMember' qua việc sử dụng trực tiếp' new' và '.'. Nếu bạn tò mò bạn nên làm thế nào những hình thức đường hóa macroexpand để '.' và' mới' hình thức. – cgrand

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