2010-03-22 27 views
27

Các tính năng nào ít được biết đến nhưng hữu ích hơn của Clojure bạn có thấy mình đang sử dụng không? Cảm thấy tự do để chia sẻ các thủ đoạn và thành ngữ nhỏ, nhưng hãy cố gắng hạn chế bản thân với Core và Contrib.Các tính năng ẩn của Clojure

Tôi tìm thấy một số thông tin thực sự thú vị trong câu trả lời cho những câu hỏi tương tự:

Có rất nhiều câu hỏi "Tính năng ẩn" khác cho các ngôn ngữ khác, vì vậy tôi nghĩ sẽ tốt hơn nếu có một cho Clojure nữa.

Trả lời

12

Các đọc eval đọc vĩ mô: #=

(read-string "#=(println \"hello\")") 

Macro này có thể trình bày một nguy cơ bảo mật nếu read được sử dụng trên người dùng nhập vào (mà có lẽ là một ý tưởng tồi ngày của riêng mình). Bạn có thể tắt macro này bằng cách đặt *read-eval* thành false.

24

Clojure có kiểu dữ liệu hàng đợi không đổi, dai dẳng, PersistentQueue, nhưng chưa (có?) Có cú pháp đọc văn bản hoặc hàm mũ Clojure, vì vậy bạn phải tạo một hàm qua cuộc gọi Java. Hàng đợi conj (đẩy) vào phía sau và bật từ phía trước với hiệu suất tốt.

user> (-> (clojure.lang.PersistentQueue/EMPTY) 
      (conj 1 2 3) 
      pop) 
(2 3) 

Liệt kê liên kết phía trước và bật từ phía trước. Vectơ kết vào phía sau và bật từ phía sau. Vì vậy, hàng đợi đôi khi chính xác những gì bạn cần.

user> (->() 
      (conj 1 2 3) 
      pop) 
(2 1) 
user> (-> [] 
      (conj 1 2 3) 
      pop) 
[1 2] 
+0

WOW. popping 100000 mục ra khỏi danh sách máy tính của tôi mất ~ 12ms. Chuyển đổi danh sách thành hàng đợi VÀ mở tất cả mọi thứ mất ~ 0.2. Đó là một trợ giúp lớn trong chương trình tôi đang viết. – MBCook

13
(defn foo [a & [b c]] ...) 

Bạn có thể destructure đối số còn lại.

Cập nhật:

Mới nhất cam kết git repo (29389970bcd41998359681d9a4a20ee391a1e07c) đã làm cho nó có thể để thực hiện destructuring kết hợp như vậy:

(defn foo [a & {b :b c :c}] ...) 

Việc sử dụng rõ ràng của việc này là cho các đối số từ khóa. Lưu ý rằng cách tiếp cận này ngăn cản các đối số từ khóa trộn lẫn với các đối số còn lại (không phải đó là điều mà một người có thể cần rất thường xuyên).

(defn foo [a & {:keys [b c] :or {b "val1" c "val2"}] ...) 

Nếu bạn muốn giá trị mặc định cho đối số từ khóa.

+0

Hm, tôi đã không nhận ra rằng việc chỉnh sửa trong các tin tức nóng sẽ cho tôi phần lớn trong câu trả lời này ... Tôi nghĩ rằng bây giờ tôi chỉ có ý tưởng đằng sau điều wiki cộng đồng này. @dnolen: Xin đừng ngần ngại "làm lại" cái này nếu nó quan trọng bằng cách nào đó. –

8

Bạn có thể apply chức năng cho chuỗi đối số vô hạn. Ví dụ:

(apply concat (repeat '(1 2 3))) 

tạo ra một chuỗi lười 1,2,3,1,2,3 ... Tất nhiên để làm việc chức năng này cũng phải lười với danh sách đối số của nó.

+1

Có một cách tốt hơn để thực hiện điều này (chu kỳ '(1 2 3)) – nickik

+2

@nickik: Tất nhiên - '(lặp lại' (1 2 3))' chỉ có nghĩa là một chuỗi trình tự vô hạn ví dụ để chỉ ra cách '(áp dụng concat ...)' hoạt động. –

7

Từ trang web ClojureDocs càng tốt một thành ngữ sử dụng juxt http://clojuredocs.org/clojure_core/clojure.core/juxt

 
;juxt is useful for forking result data to multiple termination functions 
(->> "some text to print and save to a file" 
    ((juxt 
    println 
    (partial spit "useful information.txt")))) 

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