为什么CASE不能用于字符串值而只能用于符号值?

时间:2013-09-18 17:40:46

标签: lisp common-lisp land-of-lisp

在书籍'lisp之乡'中我读了

  

因为case命令使用eq进行比较,所以通常使用它   仅用于符号值的分支。它不能用于分支   字符串值,等等。

请解释原因?

3 个答案:

答案 0 :(得分:13)

另外两个优秀的答案确实回答了问题。我会尝试回答下一个自然的问题 - 为什么case使用eql

原因实际上与C中相同(其中相应的switch语句使用数字比较):Lisp中的case表单通常编译为{{1} },因此goto比相应的cond更有效。这通常是通过将(case x (1 ...) (2 ...) (3 ...))编译为哈希表查找来实现的,哈希表查找将直接比较的值映射到子句。

那就是说,下一个问题是 - 为什么没有case变体与case哈希表子句查找而不是equal?嗯,这不是ANSI标准,但实现可以提供这样的扩展,例如CLISP中的ext:fcase

另见why eql is the default comparison

答案 1 :(得分:10)

具有相同内容“foo”和“foo”的两个字符串不是EQL。 CASE使用EQL作为比较(不是EQ,如您的问题)。通常,人们可能需要不同的测试:例如,字符串比较大小写和不区分大小写。但是对于CASE on不能使用另一个测试。 EQL是内置的。 EQL比较指针相等,数字和字符。但不是字符串内容。但是,您可以测试两个字符串是否是相同的数据对象。

因此,两个字符串"FOO""FOO"通常是两个不同的对象。

但是两个符号FOOFOO通常是同一个对象。这是Lisp的基本功能。因此,它们EQLCASE可用于比较它们。

答案 2 :(得分:5)

因为(eq "foo" "foo")不一定是真的。每次键入字符串文字时,它都可以创建一个新的唯一字符串。因此,当CASE将值与EQ案例中的文字进行比较时,它们将不匹配。