2015-04-04 59 views
1

我仍然有问题需要真正掌握case。我明白你提供使用eq内部比较符号,但是我不知道如果我得到一个正确的事情:使用带有一个或多个符号的案例

我已经看到,我可以写,如:

(case n 
    (23 'foo) 
    (42 'bar) 
    (otherwise 'something-else)) 

我也可以这样写:

(case n 
    ((23 42) 'foo-or-bar) 
    (otherwise 'something-else)) 

所以,我说的对,如果我指定一个列表,case然后检查是否变量n比赛列表中的元素之一,但如果我指定一个单一的值,然后case直接匹配这个值?

换句话说:如果我只有一个值,可以使用非列表版本吗?

+0

你为什么不尝试它?转到lisp提示符并输入内容,如'(let((n 3))(case n((2 3)'foo)(4'bar)))'。但是,是的,这是正确的。 – lurker 2015-04-04 15:32:45

回答

4

键是键

的概念列表概念每个子句使用密钥列表。测试密钥将与键列表中的每个键进行比较。

关键列表(foo bar baz)正好是(foo bar baz)

钥匙foo被认为表示(foo)。它有助于编写更短的代码。

(case x 
    (foo  41) 
    ((bar baz) 42))) 

T的例外,否则

注意otherwise(otherwise)t(t)有例外。你需要写(otherwise),如果你想匹配的符号:

(case 'otherwise 
    ((otherwise) 'the-symbol-otherwise) 
    (otherwise 'the-otherwise-clause)) 

EQ与EQL

还要注意的是,在Common Lisp的大多数比较默认与EQL,不EQ完成。 EQ是指针相等,EQL也适用于数字和字符。

+0

好吧,那么'否则'的特殊情况下,总是使用括号可能是个好主意,对吧? – 2015-04-04 15:47:03

+0

@GoloRoden:大多数代码不会为单个项目键列表使用括号。 – 2015-04-04 15:48:15

+0

好的。感谢:-) – 2015-04-04 15:48:32

2

这不是直接回答你的问题,但我们可以使用lisp来查看它在做什么。

如果在CLHS页面查找case我们可以看到它是一个宏观的,这意味着我们可以macroexpand它,看它变成什么成

因此,让我们第一个例子

(case n 
    (23 'foo) 
    (42 'bar) 
    (otherwise 'something-else)) 

这种扩展到

(LET ((#:G1246 N)) 
    (COND ((EQL #:G1246 '23) NIL 'FOO) 
     ((EQL #:G1246 '42) NIL 'BAR) 
     (T NIL 'SOMETHING-ELSE))) 

#:G1246是我们能想到的一个象征保证通过口齿不清唯一一个gensym ..我会只是将其重命名为tmp现在

(let ((tmp n)) 
    (cond ((eql tmp '23) nil 'foo) 
     ((eql tmp '42) nil 'bar) 
     (t nil 'something-else))) 

而且cond是一个宏观的..让我们来看看如何扩展(我已经简化它有点像上文)

(let ((tmp n)) 
    (if (eql tmp '23) 
     'foo 
     (if (eql tmp '42) 
      'bar 
      'something-else))) 

现在我们可以看到所有的逻辑

现在,让我们展开下一个

(case n 
    ((23 42) 'foo-or-bar) 
    (otherwise 'something-else)) 

成为s

(let ((tmp n)) 
    (if (or (eql tmp '23) (eql tmp '42)) 
     'foo-or-bar 
     'something-else)) 

Macroexpand是该死的有用的。希望这可以帮助

+0

这确实非常有帮助,感谢详细的解释:-)) – 2015-04-04 20:26:14

+1

哦,如果你使用emacs与粘液,然后将光标停留在开始paren和'Ctrl + Return'这将扩大到一个新的缓冲区,然后可以展开内部宏或使用撤消“解除展开”它们。宏观展望的这种探索性使用非常具有启发性。 (Vim slimv也会有一个键绑定,但我不知道它是什么) – Baggers 2015-04-04 21:39:41