使用基础语言无法做到这一点。可以定义
defun
喜欢宏这样做。你愿意吗
只有
允许将这些值设置为true,或者您希望给出除
t
(或
nil
是吗?第一种情况可以通过编写一些宏来完成。第二种情况不能很好地解决(特别是
(mac :a :b)
做
a <- t; b <- t
或
a <- :b
?)
您可以为Common Lisp编写以下内容:
(defmacro keyset-bind (keys-and-vars form &body body)
(let (syms vars
(keyv (gensym "KEY")))
(loop for key in keys-and-vars
for sym = (if (consp key)
(car key)
(intern (symbol-name key) "KEYWORD"))
for var = (if (consp key) (cadr key) key)
collect sym into symst
collect var into varst
finally (setf syms symst vars varst))
`(let ,vars
(loop for ,keyv in ,form
do (case ,keyv
,@(loop for sym in syms
for var in vars
collect `((,sym) (setf ,var t)))
(t (error "unrecognised keyword ~a" ,keyv))))
,@body)))
然后你可以像这样使用它:
(defun mac (&rest switches)
(keyset-bind (a b (:t foo)) switches
(list a b foo)))
CL-USER> (mac :a)
(T NIL NIL)
CL-USER> (mac :b :t)
(NIL NIL T)
CL-USER> (mac :baz)
;; Error ...
可以写一个替代方案
defun公司
已接受(例如a)
&switch
参数类型,但您需要决定如何使其与其他参数类型和关键字交互,以及
&allow-other-keys
和
:allow-other-keys t
。一般来说,所有这一切都是一个坏主意,不鼓励与上述内容混合使用(甚至使用),因为这样很难知道一个不熟悉的函数调用是被解释为普通关键字还是一组关键字。如果您想要一种支持这种类型的语言,请查看perl6,其中关键字是键值对类型,并且有特殊的语法
key => true
和
key => false
。