3 ответов:
С Common Lisp: Предикаты Равенства
(eq x y)true если и только еслиxиyтот же самый идентичный объект.The
eqlпредикат истинен, если его аргументыeq, или если это числа одного типа с одинаковым значением, или если это символьные объекты, представляющие один и тот же символ.The
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.
еще некоторые замечания:
большинство функций CL неявно используют EQL, когда тест не указан
Смотрите также строки равны, = и дерево-равной
в основе эквалайзера обычно лежит сравнение указателей
и приблизительного ориентира:
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.
с здесь и слайды моего учителя
eq проверяет, являются ли его аргументы(представленные одним и тем же фрагментом памяти компьютера) одним и тем же символом или нет.
Например:
(eq ‘A ‘B) NIL
(eq ‘RAM ‘RAM) T
(ЭИ (свод 'на 'B) (минусы на' B')) ; это потому, что разные вызовы выполняются для обоих минусов, поэтому они, очевидно, будут выделены разные куски памятиeql первые тесты, чтобы увидеть, если его аргументы удовлетворяют EQ, если нет, он пытается увидеть, если они это числа одного типа и значения.
Например:
(eql 4 4.0) NIL
(eql 4 4) Tтеперь обратите внимание на разница:
(eq 4.0 4.0) NIL; зависит от платформы, как описано в первом (принятом) ответе
(eql 4.0 4.0) T; тип и значение аргументов: то же самоев некоторых реализациях (eq 4.0 4.0) может возвращать true, потому что в стандарте не указано, должна ли реализация хранить в памяти только одну копию чисел и символов, как это происходит с символами).как правилоне используйте эквалайзер для чисел и символов,если вы действительно знаете, что вы делаете.
равной является" более здравой " функцией сравнения. Как правило, вы можете подумайте об этом, как о том, чтобы сказать вам, выглядят ли два объекта одинаково (структурно похожие или изоморфные). Вероятно, это оператор, который вы хотите использовать для общего равенства. Он ведет себя как eql для чисел, символов и символов, но для списков (conses) и строк он сообщает, если их элементы
Например:
(равно 4 4) T
(равно (+ 2 2) 4) Tтеперь обратите внимание на разница
(eql (cons ' a ' b) (cons 'a 'b)) ноль
(равенства (минусы 'а 'б) (минусы 'А 'Б)) Т ; equal обычно верно для вещей, которые печатают то же самоеequalp как равный, просто более продвинутый. Сравнение чисел является нечувствительным к типу. Сравнение символов и строк не зависит от регистра.
Например:
(equalp (cons ' a ' b) (cons 'a 'b)) T ;то же самое, что и равный
теперь обратите внимание a разница
равно (4 4.0) NIL
equalp (4 4.0) T;как equalp обрабатывает номера типа нечувствительно
Comments