2009-02-13 123 views

回答

66

Common Lisp: Equality Predicates

(eq x y)当且仅当xy是相同的同一对象是真实的。

如果eql谓词的参数是eq,或者它们是具有相同值的相同类型的数字,或者它们是表示相同字符的字符对象,则谓词为true。

如果equal的参数的结构类似(同构)对象,则该谓词为真。一个粗略的经验法则是,两个对象是相等的,当且仅当它们的打印表示是相同的。

两个对象如果相等,则为equalp;如果它们是字符并且满足char-equal,忽略字母大小写和字符的某些其他属性;如果它们是数字并且具有相同的数值,即使它们具有不同的类型;或者它们的组件全部是equalp

这里有一些例子来自同一页我连接到上面:

(eq 'a 'b) is false. 
(eq 'a 'a) is true. 
(eq 3 3) might be true or false, depending on the implementation. 
(eq 3 3.0) is false. 
(eq 3.0 3.0) might be true or false, depending on the implementation. 
(eq #c(3 -4) #c(3 -4)) 
    might be true or false, depending on the implementation. 
(eq #c(3 -4.0) #c(3 -4)) is false. 
(eq (cons 'a 'b) (cons 'a 'c)) is false. 
(eq (cons 'a 'b) (cons 'a 'b)) is false. 
(eq '(a . b) '(a . b)) might be true or false. 
(progn (setq x (cons 'a 'b)) (eq x x)) is true. 
(progn (setq x '(a . b)) (eq x x)) is true. 
(eq #\A #\A) might be true or false, depending on the implementation. 
(eq "Foo" "Foo") might be true or false. 
(eq "Foo" (copy-seq "Foo")) is false. 
(eq "FOO" "foo") is false. 


(eql 'a 'b) is false. 
(eql 'a 'a) is true. 
(eql 3 3) is true. 
(eql 3 3.0) is false. 
(eql 3.0 3.0) is true. 
(eql #c(3 -4) #c(3 -4)) is true. 
(eql #c(3 -4.0) #c(3 -4)) is false. 
(eql (cons 'a 'b) (cons 'a 'c)) is false. 
(eql (cons 'a 'b) (cons 'a 'b)) is false. 
(eql '(a . b) '(a . b)) might be true or false. 
(progn (setq x (cons 'a 'b)) (eql x x)) is true. 
(progn (setq x '(a . b)) (eql x x)) is true. 
(eql #\A #\A) is true. 
(eql "Foo" "Foo") might be true or false. 
(eql "Foo" (copy-seq "Foo")) is false. 
(eql "FOO" "foo") is false. 


(equal 'a 'b) is false. 
(equal 'a 'a) is true. 
(equal 3 3) is true. 
(equal 3 3.0) is false. 
(equal 3.0 3.0) is true. 
(equal #c(3 -4) #c(3 -4)) is true. 
(equal #c(3 -4.0) #c(3 -4)) is false. 
(equal (cons 'a 'b) (cons 'a 'c)) is false. 
(equal (cons 'a 'b) (cons 'a 'b)) is true. 
(equal '(a . b) '(a . b)) is true. 
(progn (setq x (cons 'a 'b)) (equal x x)) is true. 
(progn (setq x '(a . b)) (equal x x)) is true. 
(equal #\A #\A) is true. 
(equal "Foo" "Foo") is true. 
(equal "Foo" (copy-seq "Foo")) is true. 
(equal "FOO" "foo") is false. 


(equalp 'a 'b) is false. 
(equalp 'a 'a) is true. 
(equalp 3 3) is true. 
(equalp 3 3.0) is true. 
(equalp 3.0 3.0) is true. 
(equalp #c(3 -4) #c(3 -4)) is true. 
(equalp #c(3 -4.0) #c(3 -4)) is true. 
(equalp (cons 'a 'b) (cons 'a 'c)) is false. 
(equalp (cons 'a 'b) (cons 'a 'b)) is true. 
(equalp '(a . b) '(a . b)) is true. 
(progn (setq x (cons 'a 'b)) (equalp x x)) is true. 
(progn (setq x '(a . b)) (equalp x x)) is true. 
(equalp #\A #\A) is true. 
(equalp "Foo" "Foo") is true. 
(equalp "Foo" (copy-seq "Foo")) is true. 
(equalp "FOO" "foo") is true. 
25

一些更多的注意事项:

  • 时没有指定测试

  • 大多数CL功能隐含使用EQL

  • 另请参见STRING-EQUAL和= TREE-EQUAL

  • 在EQ的核心通常是一个指针比较

而且一个粗略的指南:

 
To compare against...  Use... 

Objects/Structs   EQ 

NIL      EQ (but the function NULL is more concise and probably cheaper) 

T       EQ (or just the value but then you don't care for the type) 

Precise numbers   EQL 

Floats      = 

Characters     EQL or CHAR-EQUAL 

Lists, Conses, Sequences EQ (if you want the exact same object) 
          EQUAL (if you just care about elements) 

Strings     EQUAL (case-sensitive), EQUALP (case-insensitive) 
          STRING-EQUAL (if you throw symbols into the mix) 

Trees (lists of lists)  TREE-EQUAL (with appropriate :TEST argument) 

注意,对于效率通常EQ >> EQL >> EQUAL >> EQUALP。

11

here和我的老师滑梯

EQ测试,看看它的参数(由计算机内存的同一块表示)是相同的符号或没有。

例如:

(当量 'A' B)NIL
(当量 'RAM' RAM)笔
(当量(利弊 'A 'B)(利弊一个' B')) ; 这是因为不同的呼叫两个缺点做,使他们显然会被分配不同的内存块

EQL第一次测试,看看它的参数满足EQ,如果不是,它会尝试看看他们是否 是相同类型和值的数字。

例如:

(EQL 4 4.0)NIL
(EQL 4 4)T

现在请注意一个

(当量4.0 4.0)NIL;依如第一个(接受的)答案
(eql 4.0 4.0)中所述的平台上;参数的类型和值是相同的

在某些实现(例如4.0 4.0)上可能会返回true,因为它没有在标准中指定实现是否应该只在内存中保留一个数字和字符的副本,就像它在符号中一样)。根据经验不要在数字和字符上使用eq,除非你真的知道你在做什么。

等于是“理智的”比较函数。作为一个经验法则,你可以把它看作告诉你两个物体看起来是否相同(结构相似或同构)。这可能是您想要用于普遍平等的运营商。它的行为就像EQL数字,字符和符号,但对于列表(conses之外)和字符串它告诉如果它们的元素

例如:

(等于4 4)T
(等于(+ 2 2)4)T

现在请注意一个

(EQL(利弊 'A' b)(利弊 'A' b))的NIL
(等于(利弊 'A' b)(利弊'a'b))T; 等于对的事情,打印相同

equalp就像是平等的,只是更先进通常为true。数字的比较是类型不敏感的。字符和字符串的比较不区分大小写。

例如:

(equalp(利弊 'A' B)(利弊 'A' B))笔; 相同等于

现在请注意一个

等于(4 4.0)NIL
equalp(4 4.0)笔; 由于equalp对待数字类型不敏感