2009-04-04 28 views
51

Trong Common Lisp bạn có thể làm điều này:luận Clojure từ khóa

(defun foo (bar &key baz quux) 
    (list bar baz quux)) 

(foo 1 :quux 3 :baz 2) ; => (1 2 3) 

Clojure không có đối số từ khóa. Một giải pháp thay thế là:

(defn foo [bar {:keys [baz quux]}] 
    (list bar baz quux)) 

(foo 1 {:quux 3 :baz 2}) ; => (1 2 3) 

Đó là quá nhiều dấu ngoặc ôm phải nhập và đọc mọi lúc. Nó cũng yêu cầu một bản đồ băm rõ ràng để được truyền vào như một đối số chứ không phải là một danh sách phẳng.

Clojure thành ngữ nhất tương đương với các đối số từ khóa không giống ai đó đã đặt ra dấu chấm câu?

+3

Kể từ khi câu hỏi này là từ khóa hoạt động cuối cùng destructuring ràng buộc đã được thêm vào Clojure. Tôi đã cung cấp một câu trả lời để cho biết điều này. –

+1

@Brian bạn nên cân nhắc cập nhật câu trả lời được chấp nhận. –

Trả lời

39

Một cách đơn giản để mô phỏng args từ khóa trong clojure đang sử dụng băm-bản đồ trên các thông số còn lại như thế này:

> (defn kwtest [x & e] (:foo (apply hash-map e))) 
#'user/kwtest 
> (kwtest 12 :bar "ignored" :foo "returned") 
"returned" 

Giàu Hickey cung cấp một macro trong this message from the clojure google group cung cấp cho bạn các thông số từ khóa. corresponding thread chứa thông tin về lý do tại sao thông số từ khóa không được clojure hỗ trợ. Về cơ bản để tránh chi phí thời gian chạy. Giàu giải thích các phương pháp tôi đã trình bày ở trên trong this message

+0

Xem [Câu trả lời của Alex Stoddard] (http://stackoverflow.com/questions/717963/clojure-keyword-arguments/3969693#3969693); hỗ trợ cho từ khóa args đã được thêm vào tham số ràng buộc. –

10

Một phần vừa thêm vào clojure.contrib.defdefnk vĩ mô, cho phép định nghĩa các chức năng với các đối số từ khóa (xem here).

94

Để cập nhật câu trả lời này cho Clojure 1.2 hiện nay có từ khóa đầy đủ arg hỗ trợ với giá trị mặc định được cung cấp bởi các hình thức bản đồ của destructuring binding:

user> (defn foo [bar &{ :keys [baz quux] 
         :or {baz "baz_default" quux "quux_default"}}] 
     (list bar baz quux)) 
#'user/foo 

user> (foo 1 :quux 3) 
(1 "baz_default" 3) 
+7

Tôi nghĩ rằng điều này nên được thúc đẩy là câu trả lời? – john2x

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