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

7
根据GigaMonkeys上的Functions,Common Lisp通过&optional支持可选位置参数,并且默认值可以任意设置。
默认的默认值是nil
(defun function (mandatory-argument &optional optional-argument) ... )

默认值可以任意设置

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

有没有一种方法可以区分那些传递了默认值的可选参数和根本没有传递值的情况?
编辑:显然,我链接的页面解释了这一点。
有时候,我们想知道可选参数的值是由调用者提供还是使用默认值。你可以在默认值表达式之后添加另一个变量名到参数规范中,这个变量将绑定到true,如果调用者实际上为该参数提供了一个参数,并且绑定到NIL否则。按照惯例,这些变量通常与实际参数命名相同,结尾加上“-supplied-p”。例如:
(defun foo (a b &optional (c 3 c-supplied-p)) 
    (list a b c c-supplied-p))

1
这也适用于关键字参数。例如,请参见LISP:关键字参数,supplied-p - Joshua Taylor
这个问题在你提供的同一个链接中已经得到了回答! - PuercoPop
1个回答

14
根据规范,您可以在可选参数后添加另一个变量名。如果指定了可选参数,则该变量将绑定到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

在第一个情况下,可选参数被指定为函数的结果。
在第二种情况下,未指定可选参数,则结果为第一个参数。
在最后一种情况下,即使可选参数的值等于默认值,函数也可以区分实际上已经指定了参数,并返回该值。

1
常见的命名约定是使用p或-p后缀来命名提供的指示器。 - Joshua Taylor

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