LISP:关键字参数,提供-p

ech*_*hox 10 lisp common-lisp

目前我正在通过Peter Seibel的"Practical Common Lisp"工作.

在"实用:简单数据库"(http://www.gigamonkeys.com/book/practical-a-simple-database.html)一章中,Seibel通过以下示例解释了关键字参数和提供参数的用法:

(defun foo (&key a (b 20) (c 30 c-p)) (list a b c c-p))
Run Code Online (Sandbox Code Playgroud)

结果:

(foo :a 1 :b 2 :c 3)  ==> (1 2 3 T)
(foo :c 3 :b 2 :a 1)  ==> (1 2 3 T)
(foo :a 1 :c 3)       ==> (1 20 3 T)
(foo)                 ==> (NIL 20 30 NIL)
Run Code Online (Sandbox Code Playgroud)

因此,如果我在参数列表的开头使用&key,我可以使用3个参数名称,默认值和第三个参数列表,如果参数是否已提供.好.但是看看上面例子中的代码:

(list a b c c-p)
Run Code Online (Sandbox Code Playgroud)

lisp解释器如何知道cp是我的"提供的参数"?

Rai*_*wig 15

让我们重新启动函数foo:

(defun foo (&key a
                 (b 20)
                 (c 30 c-p))
   (list a b c c-p))
Run Code Online (Sandbox Code Playgroud)

如果你这样缩进,你会发现该函数有三个关键字参数:a,b和c.这些可以在函数体中使用.

对于关键字参数c,有一个变量声明为cp,它将是T或NIL,具体取决于在调用foo时是否已传递c.

关键字参数通常可以声明为以下选项之一:

  1. 作为单个变量名称
  2. 变量名称和默认值的列表
  3. 变量名称列表,默认值和变量,它将显示调用函数时是否传递了参数

当想要查看值是来自调用还是默认值时,included-p特别有趣:

(defun make-my-array (size &key (init-value nil init-value-supplied-p))
   (if init-value-supplied-p
       (make-array size :initial-element init-value)
       (make-array size)))
Run Code Online (Sandbox Code Playgroud)

现在用户可以将元素初始化为NIL:

(make-my-array 10 :init-value nil)
Run Code Online (Sandbox Code Playgroud)

这里默认值和提供的值都可以是NIL,但我们需要有所作为.变量init-value-supplied-p使得可以查看变量init-value的NIL 是来自默认值还是来自函数调用.


Mar*_*tos 5

很难说出你在问什么.c-p被绑定到TNIL,这取决于是否c作为一个参数被提供.然后,该绑定可用于函数体.