4

我有许多相同长签名的功能(为简单起见在此缩短):

(defn f 
      [x & {:keys [a b c d e f g h]
            :or [a false b false c false d false e false f false g false h false]}]
      a)

我希望事先使用宏、函数甚至 def 来存储这个通用签名:

(def args `[a b c d e f g h])

(defn args [] `[a b c d e f g h])

(defmacro args [] `[a b c d e f g h])

但是所有这些,当我插入时

(defn f 
      [x & {:keys (args)
            :or [a false b false c false d false e false f false g false h false]}]
      a) 

最终出现错误,例如

CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:1) 

所以我的两个问题是:

  1. 有什么方法可以定义和使用这样的 commonargs吗?

  2. 如果args可以定义这样的,我也想减少它以获得:or参数:[a false b false c false d false e false f false g false h false]。这将如何完成?(我问的是,如果一个工作定义args可能足够奇怪以至于这不再简单。)

4

1 回答 1

6

问题是 a 中的参数向量内的东西defn没有被评估。但是,您可以定义自己的 版本defn,如下所示:

user=> (defmacro mydefn [name & body] `(defn ~name ~'[a b c] ~@body))
#'user/mydefn
user=> (mydefn f (+ a b))
#'user/f
user=> (f 1 2 4)
3

注意~'参数的需要。否则 syntax-quote ( `) 会将符号限定为user.aetc。

于 2012-10-17T16:14:29.223 回答