Clojure:使用宏或def定义函数参数/签名

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. 有没有办法定义和使用这样一个公共的 args

  2. 如果可以定义这样的 args,我还想将其缩减以获取 :or 参数:[a false b false c false d false e false f false g false h false]。如何做到这一点?(我问这个问题是因为,如果 args 的工作定义足够奇怪,那么这可能不再是直截了当的)

1个回答

6

问题在于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

注意参数需要使用~'。否则,语法引用(`)会将符号限定为user.a等等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接