Common lisp 在CASE中引用匹配子句 更新

Common lisp 在CASE中引用匹配子句 更新,common-lisp,Common Lisp,我想我明白发生了什么。Lisp只将匹配子句的'部分'(1 2 3)和'(41 42 43)视为键(因为它们都扩展到(Quote…并且从这个角度来看,第三个代码段中的第二个=(Quote)是“重复键”(事实上,它根本不是一个键。这只是我的一个语法错误)。 我认为我的主要问题是我没有正确理解编译器警告 原职 我不理解案例(或sbcl)的以下行为 在这篇文章中,R.Joswig指出,大小写表单中的匹配子句不被评估,也不被视为文本。因此,匹配子句不应该被引用 不知道这一点,我引用了一个匹配子句,但忘了引

我想我明白发生了什么。Lisp只将匹配子句的
'
部分
'(1 2 3)
'(41 42 43)
视为键(因为它们都扩展到
(Quote
…并且从这个角度来看,第三个代码段中的第二个
=
(Quote
)是“重复键”(事实上,它根本不是一个键。这只是我的一个语法错误)。

我认为我的主要问题是我没有正确理解编译器警告

原职 我不理解
案例
(或sbcl)的以下行为

在这篇文章中,R.Joswig指出,
大小写
表单中的匹配子句不被评估,也不被视为文本。因此,匹配子句不应该被引用

不知道这一点,我引用了一个匹配子句,但忘了引用另一个。我不明白的是,为什么编译器不抱怨我引用了一个匹配子句,而抱怨我引用了两个匹配子句。具体来说:

> (let ((x 42))
     (case x
       ((1 2 3) 'first-branch)
       ('(41 42 43) 'second-branch)))      ; <=  second match clause quoted
NIL

为什么编译器只在我引用了两个匹配子句时才抱怨,而在我只引用了一个匹配子句时却不抱怨?

因为
case
没有计算,所以当
引用这两种情况时,代码相当于:

(let ((x 2 ))
 (case x
   ((QUOTE (1 2 3)) 'first-branch)           
   ((QUOTE (41 42 43)) 'second-branch)))

这意味着您的两种形式都有文字
QUOTE
,这导致了警告消息。

只是为了说明:这里的QUOTE符号只是另一个没有任何特定含义的符号。Common Lisp在
case
表达式的子句头中需要一个常量原子,如
foo
,或者一个常量列表t原子类似于
(foo-bar-baz)
。还请注意,Lisp使用
eql
作为比较-因此它在数字和字符的情况下会比较标识或值,但不会比较内容

此示例显示,
quote
只是
case
子句中的另一个符号:

CL-USER> (case 2
           ((quote foo) 'foo)
           ((quote bar) 'bar))
WARNING: Duplicate key QUOTE in CASE form, occurring in the first clause:
  ('FOO 'FOO), and the second clause:
  ('BAR 'BAR).
NIL
如果我们写的是
baz
而不是
quote
,我们会得到同样的警告:

CL-USER> (case 2
           ((baz foo) 'foo)
           ((baz bar) 'bar))
WARNING: Duplicate key BAZ in CASE form, occurring in the first clause:
  ((BAZ FOO) 'FOO), and the second clause:
  ((BAZ BAR) 'BAR).
NIL

是的,谢谢。你说得更简洁。
扩展为
(QUOTE
,由于
QUOTE
后的空格,Lisp认为“我只打算将字面
QUOTE
作为匹配子句。而且因为我在两行前面都有
,Lisp认为我有一个重复的键
QUOTE
(除了我的语法有缺陷这一事实之外)。空格与此无关。您可以在两种形式中匹配名为
quote
的符号或给定的三个元素的文字列表。不计算子句。
(let ((x 2 ))
 (case x
   ((QUOTE (1 2 3)) 'first-branch)           
   ((QUOTE (41 42 43)) 'second-branch)))
CL-USER> (case 2
           ((quote foo) 'foo)
           ((quote bar) 'bar))
WARNING: Duplicate key QUOTE in CASE form, occurring in the first clause:
  ('FOO 'FOO), and the second clause:
  ('BAR 'BAR).
NIL
CL-USER> (case 2
           ((baz foo) 'foo)
           ((baz bar) 'bar))
WARNING: Duplicate key BAZ in CASE form, occurring in the first clause:
  ((BAZ FOO) 'FOO), and the second clause:
  ((BAZ BAR) 'BAR).
NIL