我正在尝试使用case语句来使一些代码更具可读性。它似乎作为一系列if语句起作用,但由于某种原因,case语句总是接受与nil的比较,即使它不是真的。有人可以澄清为什么会出现这种情况吗?
示例:
> (case 'a
(nil nil)
(otherwise 'b))
NIL
> (case 'a
('a 'b)
(otherwise nil))
B
在上面的例子中,第一个实例返回nil,即使'显然不是nil。尝试使用if语句按照我的预期执行相同的操作:
> (if (eq 'a nil) nil 'b)
B
> (if (eq 'a 'a) 'b nil)
B
我假设有一些关于我不理解的案例陈述的行为。任何帮助将不胜感激。
编辑: 只是为了澄清,我知道'不会被评估。我只是嘲笑这个例子来创建一个情况,其中case语句的目标肯定不是零。
我正在使用xlisp-plus,但我将尝试一个真正的clisp安装,看看它是否表现不同。
编辑(再一次): 安装了CLISP,它在那里工作正常。为什么xlisp不同,调查为什么不值得。感谢所有人的理智检查。
答案 0 :(得分:3)
CASE
中的每个关键规范可以是文字列表或单个原子。但是,CLtL says that the atom must not be NIL
因为它是文字NIL
还是空列表是不明确的。请改为使用NIL
列表:
> (case 'a
((nil) nil)
(otherwise 'b))
B
> (case nil
((nil) nil)
(otherwise 'b))
NIL
答案 1 :(得分:2)
Common Lisp期望CASE要测试的项目是原子或原子列表。测试也是EQL函数。
(case 'a
(a 'b) ; EQL a
(otherwise 'foo))
(case 'a
((a b c) 'foo) ; EQL to one of a, b or c
(otherwise 'bar))
引用只是偶然的。不要使用它:
; don't use this:
(case 'a
('a 'foo) ; <- bad! , EQL to QUOTE or A
(otherwise 'bar))
以上与:
相同; don't use this:
(case 'a
((quote a) 'foo) ; <- bad! , EQL to QUOTE or A
(otherwise 'bar))
答案 2 :(得分:1)
我认为这取决于您的LISP版本。 我在Mac上有LispWorks和我的结果:
CL-USER 2 : 1 > (case 'a
(nil nil)
(otherwise 'b))
B
答案 3 :(得分:1)
与SBCL相同:
CL-USER> (case 'a
(nil nil)
(otherwise 'b))
B
也就是说,'a
是符号,因此永远不会是nil
。
答案 4 :(得分:0)
case
形式的值是隐式引用的文字列表,所以:
(case 'a
((a) 'b)
(otherwise nil))
是你想要的。 otherwise
应该有效(正如其他人所说的那样) - 请尝试t
。
BTW,当您使用'a
时,读者会将其读为(quote a)
,这意味着当值为quote
时,它也会选择它,例如:
(case 'quote
('a 'b)
(otherwise nil))