代码之家  ›  专栏  ›  技术社区  ›  Cristián Romo

在普通的lisp中,eq、eql、equal和equalp有什么区别?

  •  68
  • Cristián Romo  · 技术社区  · 16 年前

    有什么区别吗 eq , eql , equal equalp 在共同的口齿不清中?我知道其中有些检查类型,有些检查类型,但哪些检查类型?一个人什么时候比其他人更好用?

    3 回复  |  直到 16 年前
        1
  •  74
  •   nbro kai    7 年前

    Common Lisp: Equality Predicates

    (eq x y) 如果且仅当 x y 是相同的对象。

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

    这个 equal 如果谓词的参数在结构上类似(同构)对象,则谓词为true。一个粗略的经验法则是,只有当两个对象的打印表示相同时,两个对象才相等。

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

    下面是我链接到上面同一页的一些示例:

    (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.
    
        2
  •  28
  •   Leslie P. Polzer    16 年前

    更多注意事项:

    • 大多数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>>equal。

        3
  •  11
  •   A.s. Bhullar    11 年前

    here 还有我老师的幻灯片

    情商 测试其参数(由同一块计算机内存表示)是否为同一符号。

    例如:

    (eq__a__b)无
    (eq__ram_ram)t
    (等式(cons‘a’b)(cons a’b’); 这是因为对这两个缺点进行了不同的调用,因此它们显然将被分配不同的内存块。

    EQL 首先测试它的参数是否满足eq,如果不满足,它将尝试查看它们是否满足eq。 是相同类型和值的数字。

    例如:

    (EQL 4 4)零
    (EQL 4 4)t

    现在注意 差异 :

    (式4.0 4.0)无;取决于第一(接受)答案中所述的平台
    (eql 4.0 4.0)t;参数的类型和值相同

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

    平等的 是__saner_比较函数。作为经验法则,您可以将其视为告诉您两个对象看起来是相同的(结构相似还是同构)。它可能是用于一般相等的运算符。对于数字、字符和符号,它的行为类似于eql,但是对于列表(conses)和字符串,它会告知它们的元素是否

    例如:

    (等于4 4)t
    (等于(+2 2)4)t

    现在注意 差异

    (eql(cons'a'b)(cons'a'b))无
    (等于(cons'a'b)(cons'a'b))t; 对于打印相同的内容,通常是相等的。

    均等 是平等的,只是更先进。数字比较不区分类型。字符和字符串的比较不区分大小写。

    例如:

    (等于(cons'a'b)(cons'a'b))t; 平等一样

    现在注意 差异

    等于(4 4.0)零
    等于(4 4.0)t; EqualP对数字不敏感