如何在 Common Lisp 中要求关键字参数?
How to require keyword arguments in Common Lisp?
给出
(defun show-arg (a)
(format t "a is ~a~%" a))
(defun show-key (&key a)
(format t "a is ~a~%" a))
正在评估
(show-arg)
将导致错误提示 "invalid number of arguments: 0",其中
(show-key)
会显示a is NIL
如何让 SHOW-KEY
像 SHOW-ARG
那样发出错误信号?除了在函数体中使用 (unless a (error "a is required"))
之外,还有其他方法吗?我非常喜欢关键字参数并经常使用它们,并且几乎总是希望它们是必需的。
关键字参数始终是可选的,因此您需要手动检查它们是否已提供,并在需要时发出错误信号。不过最好不要关键字参数。编译器不会根据需要识别它们,因此不会在编译时为您提供缺少参数的错误消息。
如果您确实需要它们,您可以使用三元素列表指定参数;第一个元素是参数,第二个是默认值,第三个是一个变量,如果给出参数,该变量将为真。检查第三个元素比检查关键字本身更好,因为这样您就可以区分默认的 NIL
和用户作为参数提供的 NIL
。
(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)
使用它:
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.
这会在运行时出错,不幸的是在编译时不会。
给出
(defun show-arg (a)
(format t "a is ~a~%" a))
(defun show-key (&key a)
(format t "a is ~a~%" a))
正在评估
(show-arg)
将导致错误提示 "invalid number of arguments: 0",其中
(show-key)
会显示a is NIL
如何让 SHOW-KEY
像 SHOW-ARG
那样发出错误信号?除了在函数体中使用 (unless a (error "a is required"))
之外,还有其他方法吗?我非常喜欢关键字参数并经常使用它们,并且几乎总是希望它们是必需的。
关键字参数始终是可选的,因此您需要手动检查它们是否已提供,并在需要时发出错误信号。不过最好不要关键字参数。编译器不会根据需要识别它们,因此不会在编译时为您提供缺少参数的错误消息。
如果您确实需要它们,您可以使用三元素列表指定参数;第一个元素是参数,第二个是默认值,第三个是一个变量,如果给出参数,该变量将为真。检查第三个元素比检查关键字本身更好,因为这样您就可以区分默认的 NIL
和用户作为参数提供的 NIL
。
(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)
使用它:
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.
这会在运行时出错,不幸的是在编译时不会。