2009-02-13 10 views

risposta

66

Da Common Lisp: Equality Predicates

(eq x y) è vero se e solo se x e y sono lo stesso identico oggetto.

Il predicato eql è true se i suoi argomenti sono eq oppure se sono numeri dello stesso tipo con lo stesso valore o se sono oggetti carattere che rappresentano lo stesso carattere.

Il predicato equal è true se i suoi argomenti sono oggetti strutturalmente simili (isomorfi). Una regola empirica è che due oggetti sono uguali se e solo se le loro rappresentazioni stampate sono le stesse.

Due oggetti sono equalp se uguali; se sono caratteri e soddisfano char-equal, che ignora il caso alfabetico e alcuni altri attributi dei caratteri; se sono numeri e hanno lo stesso valore numerico, anche se sono di tipi diversi; o se hanno componenti che sono tutti equalp.

Ecco alcuni esempi dalla stessa pagina ho linkato sopra:

(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

Alcuni più note:

  • maggior parte delle funzioni CL implicitamente usano EQL quando non viene specificata alcuna prova

  • Vedere anche STRING-EQUAL, = e TREE-EQUAL

  • Al centro di EQ è di solito un confronto puntatore

E indicativo:

 
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) 

noti che per l'efficienza solito EQ >> EQL >> EQUAL >> EQUALP.

11

Da here e diapositive del mio insegnante

eq test per vedere se i suoi argomenti (rappresentate dallo stesso pezzo di memoria del computer) sono lo stesso simbolo o meno.

Per esempio:

(eq 'A' B) NIL
(eq 'RAM' RAM) T
(eq (cons 'un 'b) (cons un' b')) ; Questo perché diverse chiamate sono fatti per entrambe contro in modo ovviamente si procederà assegnati diversi blocchi di memoria

eql prime prove per vedere se i suoi argomenti soddisfano EQ, se non, si cerca di vedere se sono numeri dello stesso tipo e valori.

Per esempio:

(eql 4 4.0) NIL
(eql 4 4) T

Ora notare un differenza:

(eq 4.0 4.0) NIL; Depend su piattaforma come descritto nella prima risposta (accettata)
(eql 4.0 4.0) T; tipo e valore degli argomenti è lo stesso

Su alcune implementazioni (eq 4.0 4.0) può restituire true perché non è specificato nello standard se un'implementazione deve conservare solo una copia di numeri e caratteri in memoria, come con i simboli). Come regolanon utilizzare eq su numeri e caratteri, a meno che tu non sappia davvero cosa stai facendo.

pari è una funzione di confronto “più sana”. Come regola generale, puoi pensare a come ti dice se due oggetti sembrano uguali (strutturalmente simili o isomorfi). Probabilmente è l'operatore che vuoi usare per l'uguaglianza generale. Si comporta come eql per numeri, caratteri e simboli, ma per liste (conses) e le stringhe si dice se i loro elementi

Per esempio:

(pari 4 4) T
(uguale (+ 2 2) 4) T

Ora notare una differenza

(EQL (cons 'a' b) (cons 'a' b)) NIL
(pari (cons 'a' b) (cons 'a' b)) T; pari di solito è vero per le cose che la stampa lo stesso

equalp è come uguale, solo più avanzata. Il confronto dei numeri è insensibile al tipo. Il confronto di caratteri e stringhe non fa distinzione tra maiuscole e minuscole.

Per esempio:

(equalp (cons 'a' b) (cons 'a' b)) T; stessa di pari

Ora notare una differenza

uguale (4 4.0) NIL
equalp (4 4.0) T; Poiché equalp tratta i numeri digitando in modo insensibile