如何避免clojure中重复的函数参数?
我有一系列函数,它们都做不同的事情,但传递相同的数据。假设我有以下作为参数向量如何避免clojure中重复的函数参数?,clojure,Clojure,我有一系列函数,它们都做不同的事情,但传递相同的数据。假设我有以下作为参数向量 [{:keys [x y vx vy x-min x-max y-min y-max] :or {x-min 0 x-max c-width y-min 0 y-max c-height}}] 基本上,这类事情你不想重复多次。我的一个想法是做一些类似的事情 (def func-args [x y z]) (defn func func-args (+ x y z)) 如果我有一个类似的函数,那么我可以重用func
[{:keys [x y vx vy x-min x-max y-min y-max] :or {x-min 0 x-max c-width y-min 0 y-max c-height}}]
基本上,这类事情你不想重复多次。我的一个想法是做一些类似的事情
(def func-args [x y z])
(defn func func-args (+ x y z))
如果我有一个类似的函数,那么我可以重用func参数。但是,前面示例的第一行抛出一个错误,即无法解析符号x
- 有没有办法将向量成员保留为符号
- 有没有比我建议的方法更惯用的方法来减少函数参数代码膨胀
defn
要求在定义中使用文字向量,因此这不会像您建议的那样工作
最简单的方法是创建一个宏。宏允许您创建自己的语法。Clojure不鼓励使用这种(回指)宏,因为为您创建符号的宏很容易出现问题
比如:
(def cheight 100)
(def cwidth 100)
(defmacro defx [name & body]
`(defn ~name [{:keys [~'x ~'y ~'vx ~'vy ~'x-min ~'x-max ~'y-min ~'y-max]
:or {~'x-min 0 ~'x-max ~'c-width ~'y-min 0 ~'y-max ~'c-height}}]
~@body))
(defx func (+ x y))
(func {:x 1 :y 2}) ;; 3
下面是另一种方法,它接受函数args spec vector作为宏的参数:
(defmacro defn-args
[fn-name fn-args & forms]
`(defn ~fn-name ~(eval fn-args) ~@forms))
(def square-args '[x] ) ; must quote [x] here
(defn-args my-square square-args (* x x))
(my-square 3)
;=> 9
如果绑定这些向量值,就可以避免出现错误。可能真正的问题是,对于所有这些参数,函数都太复杂了。这是一种非常简洁的方法,在所有情况下只使用一个宏。