为什么在case/ecase中匹配不到nil?
Why nil cannot be matched in case/ecase?
如下形式
(let ((foo nil))
(ecase foo
(:bar 1)
(:baz 2)
(nil 3)))
引发错误 NIL fell through ECASE expression
。解决方法似乎是用括号包裹 nil
大小写,如下所示:
(let ((foo nil))
(ecase foo
(:bar 1)
(:baz 2)
((nil) 3))) ;; => 3
但为什么第一个示例不起作用?展开的 nil
大小写是否有特殊含义?
case
中的每个子句都可以匹配单个项目或项目列表,例如你可以写:
(ecase foo
(:bar 1) ;; match a specific symbol
((:baz :quux) 2)) ;; match either of these symbols
NIL
也是 Lisp 中的空列表,当它用作 case
中的测试时,它就是这样处理的,所以它永远不会匹配任何东西。同样,T
和 OTHERWISE
用于指定默认大小写,因此您不能将它们作为单个项进行匹配。要匹配其中任何一个,您需要将它们放入列表中。
从技术上讲,specification 对子句中的键进行了说明:
keys---a designator for a list of objects. In the case of case, the symbols t
and otherwise
may not be used as the keys designator. To refer to these symbols by themselves as keys, the designators (t)
and (otherwise)
, respectively, must be used instead.
和 list designator 的定义说:
a designator for a list of objects; that is, an object that denotes a list and that is one of: a non-nil atom (denoting a singleton list whose element is that non-nil atom) or a proper list (denoting itself).
请注意,单个原子被视为单个列表的情况表示 "non-nil atom"。这允许 NIL
属于第二种情况,其中一个适当的列表表示它自己。否则,将无法为空列表创建列表指示符,因为 NIL
将表示 (NIL)
.
您可能会争辩说,在 CASE
中有一个空的键列表没有多大意义,因为它永远不会匹配任何内容,并且可以省略整个子句。这种退化的情况是为了自动代码生成的好处(例如扩展为 CASE
的其他宏),因为它们可能会产生空列表,并且这些应该与其他列表一致地处理。他们将更难使子句的生成以是否有任何键为条件。
如下形式
(let ((foo nil))
(ecase foo
(:bar 1)
(:baz 2)
(nil 3)))
引发错误 NIL fell through ECASE expression
。解决方法似乎是用括号包裹 nil
大小写,如下所示:
(let ((foo nil))
(ecase foo
(:bar 1)
(:baz 2)
((nil) 3))) ;; => 3
但为什么第一个示例不起作用?展开的 nil
大小写是否有特殊含义?
case
中的每个子句都可以匹配单个项目或项目列表,例如你可以写:
(ecase foo
(:bar 1) ;; match a specific symbol
((:baz :quux) 2)) ;; match either of these symbols
NIL
也是 Lisp 中的空列表,当它用作 case
中的测试时,它就是这样处理的,所以它永远不会匹配任何东西。同样,T
和 OTHERWISE
用于指定默认大小写,因此您不能将它们作为单个项进行匹配。要匹配其中任何一个,您需要将它们放入列表中。
从技术上讲,specification 对子句中的键进行了说明:
keys---a designator for a list of objects. In the case of case, the symbols
t
andotherwise
may not be used as the keys designator. To refer to these symbols by themselves as keys, the designators(t)
and(otherwise)
, respectively, must be used instead.
和 list designator 的定义说:
a designator for a list of objects; that is, an object that denotes a list and that is one of: a non-nil atom (denoting a singleton list whose element is that non-nil atom) or a proper list (denoting itself).
请注意,单个原子被视为单个列表的情况表示 "non-nil atom"。这允许 NIL
属于第二种情况,其中一个适当的列表表示它自己。否则,将无法为空列表创建列表指示符,因为 NIL
将表示 (NIL)
.
您可能会争辩说,在 CASE
中有一个空的键列表没有多大意义,因为它永远不会匹配任何内容,并且可以省略整个子句。这种退化的情况是为了自动代码生成的好处(例如扩展为 CASE
的其他宏),因为它们可能会产生空列表,并且这些应该与其他列表一致地处理。他们将更难使子句的生成以是否有任何键为条件。