我正在通过Clojure的勇敢和真实。在宏的章节中有这样的练习:评估在Clojure中传递给def的符号
使用一个宏调用编写一个定义任意数量的属性检索函数的宏。你可以这样称呼它:
(defattrs c-int :intelligence
c-str :strength
c-dex :dexterity)
这些函数的功能是从地图中检索一个值。例如,给定:(def character {:name "Travis", :intelligence 20, :strength 23, :dexterity 13})
的(c-int character)
结果将是当然的20
这样的功能可以很容易地被定义为(def c-int #(:intelligence %))
这是我想出了解决这一问题的解决方案:
(defmacro defattrs
[& attributes]
`(let [attribute-pairs# (partition 2 (quote ~attributes))]
(map (fn [[function-name# attribute-key#]]
(def function-name# #(attribute-key# %)))
attribute-pairs#)))
我遇到的问题是def
使用生成的符号名称,而不是定义该函数的方法(根据def
的用法,这在后见之下是有意义的)。我尝试使用表达式定义与功能,如:
(let [x ['c-int :intelligence]]
(def (first x) #((second x) %)))
导致这个错误:CompilerException java.lang.RuntimeException: First argument to def must be a Symbol, compiling:(/tmp/form-init5664727540242288850.clj:2:1)
我如何能做到这一点任何想法?