在《口齿不清的土地》一书中,我读到
因为 case 命令使用 eq 进行比较,所以它通常只用于符号值的分支。除其他外,它不能用于在字符串值上进行分支。
请解释为什么?
在《口齿不清的土地》一书中,我读到
因为 case 命令使用 eq 进行比较,所以它通常只用于符号值的分支。除其他外,它不能用于在字符串值上进行分支。
请解释为什么?
其他两个出色的答案确实回答了所提出的问题。我将尝试回答自然的下一个问题——为什么case
使用eql
?
原因其实和 in 一样C
(对应的switch
语句使用数值比较):case
Lisp 中的表单通常编译成类似的形式goto
,因此(case x (1 ...) (2 ...) (3 ...))
比对应的cond
. 这通常通过编译case
到哈希表查找来完成,该查找将要比较的值直接映射到子句。
也就是说,下一个问题是 - 为什么不使用带有哈希表子句查找的case
变体而不是? 嗯,这不在 ANSI 标准中,但实现可以提供这样的扩展,例如,在 CLISP 中。equal
eql
ext:fcase
另请参阅为什么eql
是默认比较。
具有相同内容“foo”和“foo”的两个字符串不是 EQL。CASE
用作EQL
比较(不是EQ
您的问题)。通常可能需要不同的测试:例如,字符串比较大小写和不区分大小写。但是对于CASE
on 不能使用另一个测试。EQL
是内置的。EQL
比较指针相等、数字和字符。但不是字符串内容。不过,您可以测试两个字符串是否是相同的数据对象。
"FOO"
所以,两个字符串"FOO"
通常是两个不同的对象。
但是两个符号FOO
和FOO
通常实际上是同一个对象。这是 Lisp 的一个基本特性。因此,它们是EQL
并且CASE
可以用来比较它们。
因为(eq "foo" "foo")
不一定是真的。每次键入字符串文字时,它可能会创建一个新的、唯一的字符串。因此,当CASE
将值与带有 的情况下的文字进行比较时EQ
,它们将不匹配。