区分具有默认值和无值的可选参数

Distinguish &optional argument with default value from no value

根据GigaMonkeys上的Functions,Common Lisp通过&optional支持可选的位置参数,默认值可以任意设置。

默认默认值为nil

(defun function (mandatory-argument &optional optional-argument) ... )

并且默认值可以任意设置

(defun function (mandatory-argument &optional (optional-argument "")) ....)

有没有办法区分可选参数具有显式传入的默认值与根本没有值的情况?

编辑:显然我链接的页面解释了这一点。

Occasionally, it's useful to know whether the value of an optional argument was supplied by the caller or is the default value. Rather than writing code to check whether the value of the parameter is the default (which doesn't work anyway, if the caller happens to explicitly pass the default value), you can add another variable name to the parameter specifier after the default-value expression. This variable will be bound to true if the caller actually supplied an argument for this parameter and NIL otherwise. By convention, these variables are usually named the same as the actual parameter with a "-supplied-p" on the end. For example:

(defun foo (a b &optional (c 3 c-supplied-p)) 
    (list a b c c-supplied-p))

根据specification,您可以在可选参数后添加另一个变量名。如果指定了可选参数,则此变量将绑定到 t,否则将绑定到 nil

例如:

CL-USER> (defun foo (mandatory &optional (optional1 nil optional1-supplied-p))
           (if optional1-supplied-p
               optional1
               mandatory))

FOO
CL-USER> (foo 3 4)
4
CL-USER> (foo 3)
3
CL-USER> (foo 3 nil)
NIL

在第一种情况下,指定了可选参数,因此它是函数的结果。

第二种情况不指定可选参数,结果为第一个参数

在最后一种情况下,即使可选参数的值等于默认值,该函数也可以区分实际指定了一个参数,并且可以return那个值。