2009-03-24 22 views

Trả lời

21
(defmacro defn-with-str [string args & body] 
`(defn ~(symbol string) ~args [email protected])) 

(defn-with-str "print-string" [k] (println k)) 

(print-string "lol") 
+0

1. các ~ là những gì ở phía trước args? 2. ~ ở phía trước cơ thể là gì? – Belun

+1

@Belun 1. ~ = unquote 2. ~ @ = mở rộng chuỗi – Surya

+0

lý do tại sao nếu tôi làm (defn defns [] (doall (bản đồ (fn [s] (defn-with-str s [k] (println k))) ["print-string"]))) Tôi nhận được một fn gọi là 's'? – Hendekagon

14

Tôi thích dnolen của câu trả lời tốt hơn, nhưng bạn có thể làm điều này quá:

(defn #=(symbol "print-string") [k] (println k))

#=() được đánh giá tại đọc thời gian. Tôi không biết tính năng của Clojure ổn định như thế nào, tôi sẽ không dựa vào nó để không thay đổi trong tương lai. Macro là cách tôi làm.

17

giải pháp của dnolen hoạt động ở thời gian mở rộng macro, Brian Carper lúc đọc. Bây giờ, đây là một cho thời gian chạy:

(intern *ns* (symbol "a") (fn [k] (println k))) 
+0

Cool không biết về điều đó. Một báo trước là var a sẽ thiếu metadata chức năng mà bạn nhận được từ việc sử dụng defn. – dnolen

7

FYI - câu trả lời dnolen sẽ chỉ làm việc cho chuỗi chữ, và không cho chuỗi trong def'd hoặc biến let'd.

(defmacro defn-với-str [args chuỗi & cơ thể] `(defn ~ (biểu tượng string) ~ args ~ @ thân))

(def hisym "hi") (defn-với- str hisym [] (println "hi"))

Bây giờ bạn có một chức năng gọi là "hisym"

(hi) -> java.lang.Exception: Không thể giải quyết biểu tượng: hi trong bối cảnh này (NO_SOURCE_FILE : 6) (hisym) -> in "hi"

.210

Để tránh điều này, eval chuỗi tên hàm trong vĩ mô

(defmacro defn-with-str [string args & body]
`(defn ~(symbol (eval string)) ~args [email protected]))

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