目前我正在阅读“Lisp之乡”。在最近的一个代码示例中,作者给出了:
> (eq 'fooo 'FoOo)
T
证明符号不区分大小写。几页之后数据模式正式推出。
但是我没有真正了解以下内容。 eq
是一个函数,因此它的名称也不区分大小写。因此,我应该能够做到这一点:
> (eq 'Eq 'EQ)
T
大。这按预期工作。但是如果我把它放在数据模式的列表中呢?请记住,我只是在试验一些对我来说很新的东西。
> (eq '(Eq) '(EQ))
NIL
> (eq '('Eq) '('EQ))
NIL
嗯。好的?这是为什么?我原以为如果我将相同的符号放入两个列表中,那么这些列表将被认为是相同的。
现在的问题是:这是否意味着不会比较列表的内容,而是列出“对象”本身?我错过了什么?
答案 0 :(得分:4)
> (eq (print (intern "foo")) (print (intern "FOO")))
|foo| ; printed
FOO ; printed
==> NIL ; returned
(eq (read-from-string "foo") (read-from-string "FOO"))
==> T
但是,您可以使读者保留案例:
(let ((*readtable* (copy-readtable)))
(setf (readtable-case *readtable*) :preserve)
(eq (read-from-string "foo") (read-from-string "FOO")))
==> NIL
请看一下
Common Lisp provides 4 equality predicates,你应该根据自己的需要使用正确的:
(equal '(Eq) '(EQ))
==> T
(equal '('Eq) '('EQ))
==> T
答案 1 :(得分:2)
eq
比较完全相同的,认为指针相等。这与Java中的==
类似,即使逻辑上等效的数据也是假的。
这里的解决方案是使用equal
来执行“智能”操作并比较列表元素
> (equal '(A) '(a))
T
此外,符号区分大小写。但默认情况下,阅读器(将代码转换为AST的内容)默认为不区分大小写。您可以通过intern
等函数注意到这种区别。
答案 2 :(得分:1)
Lisp符号区分大小写。甚至lisp阅读器也区分大小写。唯一的一点是,当读者读取符号时,通常会将其设为大写。最简单的方法是告诉读者重要的是将它放在垂直线之间。
> '|asd|def|ghj|
|asdDEFght|
> '|asd|
|asd|
> '|ASD|
ASD
> 'ASD
ASD
> (eq 'asd '|ASD|)
t
> (eq 'asd '|aSd|)
nil
eq
谓词检查参数是否是相同的对象(类似于比较C
中变量的指针)
> (defparameter *x* 1)
> (defparameter *y* 1)
> (eq *x* *y*)
nil
因此,当您在'(asd)
中编写REPL
时,会创建包含一个元素的列表。当你第二次写它时,会创建另一个列表,这些列表实际上是不同的对象。
> (defparameter *list1* '('qwe))
> (defparameter *list2* '('qwe))
> (eq *list1* list2*) ;this are 2 different objects
nil
> (setf (first *list1* 'def))
> *list1* ;this list has changed
(DEF)
> *list2* ;and this did not
(QWE)
> (setf *list1* *list2*) ;now they are just different names for one object
> *list1*
(QWE)
> (eq *list1* *list2*)
t
还有其他方法可以比较对象(eq
eql
equal
equalp
=
)。最好阅读文档并使用REPL
来查看差异。
答案 3 :(得分:1)
稍微复杂一点。
假设我们在文件中有以下内容。然后我们编译并加载该文件。
(defparameter *a* '(1))
(defparameter *b* '(1))
现在我们计算:
(eq *a* *b*)
如果是NIL
或T
,则未定义。 Common Lisp编译器可能检测到列表是equal
并将两个变量设置为同一个列表 - 即EQ
然后也是如此。实际上有Common Lisp编译器正在这样做。在* REPL DEFPARAMETER
中执行两个one would usually expect that the Lisp system does not detect that and that
表单(eq a * b *)is
NIL`。
EQUAL
比较结构,我的示例(eq *a* *b*)
总是T
。