Common lisp 如何获取函数的参数量
我正在寻找一种方法来获取函数的参数量,一种类似下面虚构的Common lisp 如何获取函数的参数量,common-lisp,arity,parameter-list,Common Lisp,Arity,Parameter List,我正在寻找一种方法来获取函数的参数量,一种类似下面虚构的length args函数的函数: (defun func1 (arg1 arg2) ()) (defun get-count-args-func (func) (length-args func)) (get-count-args-func #'func1) ;; return 2 实际上,我真正需要的是从我的测试库中解决一个问题,这个问题是我从javascript带到lisp的,我在这里处理同步和异步测试,我需要这样做
length args
函数的函数:
(defun func1 (arg1 arg2)
())
(defun get-count-args-func (func)
(length-args func))
(get-count-args-func #'func1)
;; return 2
实际上,我真正需要的是从我的测试库中解决一个问题,这个问题是我从javascript带到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)
最简单的方法是将rest参数添加到函数中,并在函数中使用内置的length函数来确定函数使用的参数数:
CL-USER> (defun fun-1(&rest args)
(length args))
FUN-1
CL-USER> (fun-1 1 2 3)
3
对于我必须处理的情况,这不是一个选项,因为有时我传递一个“完成”参数,有时不,因为我同时处理同步和异步函数,异步需要一个“完成”参数,而同步不需要。我的搜索不是传递了多少个参数,而是函数请求了多少个参数,
get count args func
将是一个元函数,因为它处理函数元信息。我更新了我的问题,请看。@Rainer不,她在那里没有答案,她有办法。人们的搜索方式有所不同,使用另一个问题的关键词,他们可能没有找到提供路径的问题,最终会错过答案。所以我不认为这是一个重复的问题,而是一个基于另一个答案的不同问题,这是不同的事情,如果我没有把它连接到这里,你可能找不到另一个问题。你在问函数的算术,这就是另一个问题的内容,你把其中一个答案中的代码复制到了你自己的答案中。@Rainer“arity”这个词并没有出现在我的脑海中,对于很多人来说,它也不会出现。是的,所以我提供了一个链接,显示谁写了代码,它不是副本,它是引用,它是不同的东西,不要混淆术语;但你想怎么做就怎么做,你才是王者。@RainerJoswig我从编程中了解到,将事物解耦很有趣,你试图通过将这个问题标记为“重复”来实现事物的耦合,看看为什么:另一个问题是“在common lisp中查找函数的算术”,任何搜索它的人都会发现,虽然我的问题是“如何获得一个函数的参数数量”,但两个问题的答案都是一样的,对吧,完全相同的问题用不同的措辞发布并不罕见。然后可以将其标记为重复。你的问题不会消失:它会一直存在,人们可以找到它。但是,同一个问题在不同的地方有多个相同答案的版本几乎没有什么用处。这个便携库正是这样做的:
CL-USER> (defun fun-1(&rest args)
(length args))
FUN-1
CL-USER> (fun-1 1 2 3)
3