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

ska*_*404 5 lisp common-lisp land-of-lisp

在书中的'lisp之乡'我读过

因为case命令使用eq进行比较,所以它通常仅用于对符号值进行分支.除其他外,它不能用于分支字符串值.

请解释原因?

sds*_*sds 13

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

原因实际上与C(在相应的switch语句使用数字比较时)相同:caseLisp中的表单通常被编译成类似的东西goto,因此(case x (1 ...) (2 ...) (3 ...))比相应的更有效cond.这通常通过编译case到哈希表查找来实现,该哈希表查找将直接比较的值映射到子句.

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

另请参见为什么eql是默认比较.


Rai*_*wig 10

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

所以,两个字符串"FOO""FOO"通常有两种不同的对象.

但两个符号FOOFOO通常实际上是同一个对象.这是Lisp的基本功能.因此,他们EQLCASE可以用来对它们进行比较.


Bar*_*mar 5

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