Common lisp 如何在公共Lisp中要求关键字参数?
给定 评估Common lisp 如何在公共Lisp中要求关键字参数?,common-lisp,keyword-argument,Common Lisp,Keyword Argument,给定 评估 (defun show-arg (a) (format t "a is ~a~%" a)) (defun show-key (&key a) (format t "a is ~a~%" a)) 将导致显示“无效参数数:0”的错误,其中 将显示a为零 如何让SHOW-KEY发出错误信号,如SHOW-ARGdoes?除了在函数体中使用(除非有(错误“a是必需的”),还有其他方法吗?我非常喜欢关键字参数并经常使用它们,而且几乎总是希望它们是必需的。关键字参数总是可选的,
(defun show-arg (a)
(format t "a is ~a~%" a))
(defun show-key (&key a)
(format t "a is ~a~%" a))
将导致显示“无效参数数:0”的错误,其中
将显示a为零
如何让
SHOW-KEY
发出错误信号,如SHOW-ARG
does?除了在函数体中使用(除非有(错误“a是必需的”)
,还有其他方法吗?我非常喜欢关键字参数并经常使用它们,而且几乎总是希望它们是必需的。关键字参数总是可选的,因此您需要手动检查它们是否已给出,如果需要,则发出错误信号。不过,最好不要使用关键字参数。编译器不会根据需要识别它们,因此不会在编译时向您提供缺少参数的错误消息
如果确实需要,可以使用三元素列表指定参数;第一个元素是参数,第二个是默认值,第三个是一个变量,如果给定参数,则该变量为true。检查第三个元素比检查关键字本身要好,因为这样您就可以区分默认的NIL
和用户作为参数给出的NIL
之间的区别
(show-key)
编辑
现在我仔细考虑了一下,实际上有一种方法可以获得缺少关键字参数的编译时错误。为函数定义编译器宏:
(defun foo (&key (keyarg nil keyargp))
(unless keyargp (error "KEYARG is required."))
(* keyarg 2))
一种可能性是:
(defun foo (&key a b c d)
(* a b c d))
(define-compiler-macro foo (&whole whole &key (a nil ap) (b nil bp)
(c nil cp) (d nil dp))
(declare (ignore a b c d))
(unless (and ap bp cp dp)
(error "Missing arguments..."))
whole)
使用它:
(defun foo (&key (arg1 (error "missing arg1 in call to function foo")))
arg1)
这将在运行时产生错误,不幸的是不是在编译时。这方面的一个小变体是将错误的信号包装到一个小函数中,这样您就可以说
&key(foo(required))
“不过最好不需要关键字参数。”建议的方法是什么,例如初始化具有许多必填字段的记录?例如,我如何提高(制作专辑“Led齐柏林飞艇”“物理涂鸦”1979 nil t'rock)
?@leo狂躁者通常会尝试提供有意义的默认值,用户只会在必要时覆盖它们。在该示例中,前两个参数可能是唯一必需的参数,其余参数可以保留为NIL
。在大多数实际程序中,这对可读性来说并不是一个真正的问题,因为很少用文本值初始化记录。您通常会从文件/数据库/用户读取值,变量名会让读者明白它们的含义。他们还可以使用自己的开发环境(如SLIME)查看参数列表。
(defun foo (&key (arg1 (error "missing arg1 in call to function foo")))
arg1)
CL-USER 80 > (foo)
Error: missing arg1 in call to function foo
1 (abort) Return to level 0.
2 Return to top loop level 0.