我正在寻找一种获取函数参数数量的方法,该函数类似于下面的虚构length-args
函数:
(defun func1 (arg1 arg2)
())
(defun get-count-args-func (func)
(length-args func))
(get-count-args-func #'func1)
;; return 2
实际上,我真正需要的是解决我从javascript到lisp的测试库中的一个问题,在这里我同时处理同步和异步测试,在这里我需要做这样的事情(简化到最大程度)现实):
(defun test ()
;;...
)
(defun done ()
;;...
)
(defun run-test (test)
(if (>= (get-count-args-func test) 1)
(test (funcall done))
(test)))
答案 0 :(得分:0)
我通过在此处查看以下答案找到了解决此问题的方法:Find Function's Arity in common lisp,需要 arglist 函数来处理各种实现,请参见 arglist的实现:
;; function provided by @sds at https://stackoverflow.com/questions/15465138/find-functions-arity-in-common-lisp
(defun arglist (fn)
"Return the signature of the function."
#+allegro (excl:arglist fn)
#+clisp (sys::arglist fn)
#+(or cmu scl)
(let ((f (coerce fn 'function)))
(typecase f
(STANDARD-GENERIC-FUNCTION (pcl:generic-function-lambda-list f))
(EVAL:INTERPRETED-FUNCTION (eval:interpreted-function-arglist f))
(FUNCTION (values (read-from-string (kernel:%function-arglist f))))))
#+cormanlisp (ccl:function-lambda-list
(typecase fn (symbol (fdefinition fn)) (t fn)))
#+gcl (let ((fn (etypecase fn
(symbol fn)
(function (si:compiled-function-name fn)))))
(get fn 'si:debug))
#+lispworks (lw:function-lambda-list fn)
#+lucid (lcl:arglist fn)
#+sbcl (sb-introspect:function-lambda-list fn)
#-(or allegro clisp cmu cormanlisp gcl lispworks lucid sbcl scl)
(error 'not-implemented :proc (list 'arglist fn)))
现在我可以这样做:
(defun func1 (arg1 arg2)
())
(defun get-count-args-func (func)
(length (arglist func)))
(get-count-args-func #'func1) => 2
所以我有很多参数,例如,如果您有&key
,&rest
或&optional
这样的参数,那么您必须专心一点。
(defun func1 (&optional arg1 arg2)
())
(defun get-count-args-func (func)
(length (arglist func)))
(get-count-args-func #'func1) => 3
看到您得到3,因为 arglist 函数将返回:
(&OPTIONAL ARG1 ARG2)
只有返回必需的参数时,他才返回:
(ARG1 ARG2)
答案 1 :(得分:0)
最简单的方法是在函数中添加rest参数,并在函数内使用内置的length函数确定函数需要的args数量:
CL-USER> (defun fun-1(&rest args)
(length args))
FUN-1
CL-USER> (fun-1 1 2 3)
3