在Common Lisp中同时使用& rest和& key [英] use of &rest and &key at the same time in Common Lisp

查看:49
本文介绍了在Common Lisp中同时使用& rest和& key的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想同时使用& rest & key .但是,尝试的代码如下:

I want to use both &rest and &key at the same time. However, the attempted code below:

(defun test (&rest args &key (name "who")) nil)
(test 1 2 3 4 5 :name "hoge")

导致错误:

***-测试:(1 2 3 4 5:NAME"hoge")中的关键字参数应该成对出现

*** - TEST: keyword arguments in (1 2 3 4 5 :NAME "hoge") should occur pairwise

,并且当我仅给出像(test:name"hoge")这样的关键字参数时,它可以工作.可以同时使用& rest和& key吗?

and when I gives only keyword parameter like (test :name "hoge"), it works. Is it possible to use both &rest and &key?

推荐答案

在Common Lisp的函数定义中,将其余参数与关键字参数混合通常不是一个好主意.如果这样做,您可能应该考虑重写函数定义,因为它可能导致某些意外行为.如果& rest和& key都出现在参数列表中,则两种情况都会发生-所有剩余的值(包括关键字本身)都被收集到绑定到& rest参数的列表中,并且包含适当的值也绑定到& key参数.因此,默认情况下,(名称"who")关键字参数绑定到您的其余参数列表.如果您尝试输入参数(1 2 3 4 5),则会出现错误,因为它们未绑定到您的参数(名称为"who").这是一个示例:

It's generally not a good idea to mix rest parameters with keyword parameters within a function definition in Common Lisp. If you do so, you should probably consider rewriting the function definition because it can lead to some unexpected behavior. If both &rest and &key appear in a parameter list, then both things happen--all the remaining values, which include the keywords themselves, are gathered into a list that's bound to the &rest parameter, and the appropriate values are also bound to the &key parameters. So the (name "who") keyword parameter is bound to your list of rest parameters by default. if you try to enter the arguments (1 2 3 4 5), you will get an error because they aren't bound to your parameter (name "who"). Here is an example:

(defun test (&rest args &key (name "who"))
   (list args name))

这是您的函数定义.如果我们尝试调用返回参数列表的函数,则会在此处将& rest参数绑定到& key参数:

Here we have your function definition. If we try to call the function which return a list of the arguments, we will see that the &rest parameters are bound to they &key parameters here:

CL-USER> (test :name "Davis")
((:NAME "Davis") "Davis")

通过在同一参数列表中混合& rest参数和关键字参数,您将无法输入与关键字参数不匹配的任何rest参数,这就是您在此处输入breakloop的原因.

By mixing &rest parameters and keyword parameters in the same parameter list, you won't be able to enter any rest parameters that don't match your keyword parameter which is why you enter into a breakloop here.

现在,如果要创建宏,则可以从技术上在定义中使用多个参数列表,并在一个列表中添加关键字参数,在另一个列表中添加& rest(或& body)参数:

Now, if you want to create a macro, you can technically use multiple parameter lists within the definition, and add keyword parameters in one list, and &rest (or &body) parameters in the other list:

 (defmacro hack-test ((&key (name "who")) &body body)
   `(list ,name ,@body))

CL-USER> (hack-test (:name "Ricky")
                (+ 2 3))
("Ricky" 5)

CL-USER> (hack-test ()
                 (+ 2 4)
                 (+ 4 5)
                 (+ 9 9))
("who" 6 9 18)
CL-USER> 

这篇关于在Common Lisp中同时使用& rest和& key的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆