Предикаты равенства
Здесь мы описываем функции, проверяющие равенство двух объектов. Другие функции проверяют равенство содержимого объектов определённых типов, например строк. О таких предикатах см. соответствующую главу, в которой описывается тип данных.
- Функция: eq object1 object2
-
Эта функция возвращает
t, если object1 и object2 являются одним и тем же объектом, иnilв противном случае.Если object1 и object2 — символы с одинаковым именем, обычно это один и тот же объект, но см. раздел Создание и интернирование символов, где описаны исключения. Для других типов, не являющихся числами (например, списков, векторов и строк), два аргумента с одинаковым содержимым или элементами не обязательно являются
eqдруг другу: они являютсяeqтолько в том случае, если это один и тот же объект, то есть изменение содержимого одного из них отразится таким же изменением содержимого другого.Если object1 и object2 — числа разных типов или значений, они не могут быть одним и тем же объектом, и
eqвозвращаетnil. Если это фиксимы с одинаковым значением, то они являются одним и тем же объектом, иeqвозвращаетt. Если они были вычислены отдельно, но имеют одинаковое значение и одинаковый числовой тип, отличный от типа фиксиму, то они могут быть как одним и тем же объектом, так и разными объектами, аeqвозвращаетtилиnilв зависимости от того, создал интерпретатор Lisp один объект или два.Если object1 или object2 — символ с позицией,
eqрассматривает его как обычный символ, когдаsymbols-with-pos-enabledне-nil(см. раздел Символы с позицией).(eq 'abc 'abc) ⇒ t (eq 'abc 'ABC) ⇒ nil (eq ?A ?A) ⇒ t (eq 3 3) ⇒ t
Равные числа, не являющиеся фиксимами, могут быть как одним и тем же объектом, так и разными объектами:
(eq 3.0 3.0) ⇒ t or nil (eq (expt 10 50) (expt 10 50)) ⇒ t or nil
Вновь созданные изменяемые объекты различны:
(eq (list 1 2 3) (list 1 2 3)) ⇒ nil (eq (point-marker) (point-marker)) ⇒ nil
Равные константы других типов могут быть как одним и тем же объектом, так и разными объектами:
(eq "abc" "abc") ⇒ t or nil (eq '(1 2 3) '(1 2 3)) ⇒ t or nil (eq [1 2 3] [1 2 3]) ⇒ t or nil
кроме случаев, когда это одна и та же литеральная константа:
(let ((x "abc")) (eq x x)) ⇒ t (let ((x '(1 2 3))) (eq x x)) ⇒ t (let ((x [1 2 3])) (eq x x)) ⇒ t
Функция
make-symbolвозвращает неинтернированный символ, отличный от символа, который используется при записи этого имени в выражении Lisp. Различные символы с одинаковым именем не являютсяeq. См. раздел Создание и интернирование символов.(eq (make-symbol "foo") 'foo) ⇒ nilБайт-компилятор Emacs Lisp может объединять идентичные литеральные объекты, например литеральные строки, заменяя их ссылками на один и тот же объект. В результате байт-компилированный код будет сравнивать такие объекты как
eq, а интерпретируемая версия того же кода — нет. Поэтому ваш код никогда не должен полагаться на то, что объекты с одинаковым литеральным содержимым являются или не являютсяeqиeq; вместо этого следует использовать функции, сравнивающие содержимое объектов, напримерequal, описанную ниже. Аналогично, ваш код не должен изменять литеральные объекты (например, добавлять текстовые свойства к литеральным строкам), поскольку это может повлиять на другие литеральные объекты с таким же содержимым, если байт-компилятор объединит их.
- Функция: equal object1 object2
-
Эта функция возвращает
t, если компоненты object1 и object2 равны, иnilв противном случае. В то время какeqпроверяет, являются ли аргументы одним и тем же объектом,equalзаглядывает внутрь различных аргументов, чтобы проверить, совпадают ли их элементы или содержимое. Поэтому, если два объекта являютсяeq, они являютсяequal, но обратное верно не всегда.(equal 'foo 'foo) ⇒ t(equal 456 456) ⇒ t(equal "asdf" "asdf") ⇒ t(equal '(1 (2 (3))) '(1 (2 (3)))) ⇒ t(equal [(1 2) 3] [(1 2) 3]) ⇒ t(equal (point-marker) (point-marker)) ⇒ tФункция
equalсравнивает строки и булевы векторы по значению. Числа сравниваются по типу и числовому значению с помощьюeql. Списки, cons-ячейки, векторы, записи, маркеры, таблицы символов, объекты шрифтов и функциональные объекты (замыкания) сравниваются рекурсивно с помощьюequalдля составляющих их частей.При сравнении строк учитывается регистр, но не текстовые свойства — сравниваются только символы в строках. См. раздел Текстовые свойства. Чтобы также сравнивать текстовые свойства, используйте
equal-including-properties. По техническим причинам однобайтовая и многобайтовая строки являютсяequalтогда и только тогда, когда содержат одинаковую последовательность кодов символов и все эти коды находятся в диапазоне от 0 до 127 (ASCII).(equal "asdf" "ASDF") ⇒ nilЕсли object1 или object2 содержит символы с позицией,
equalрассматривает их как обычные символы, когдаsymbols-with-pos-enabledне-nil. В противном случаеequalсравнивает два символа с позицией, сравнивая их компоненты. См. раздел Символы с позицией.Другие объекты считаются
equalтолько в том случае, если они являютсяeq. Например, два различных буфера никогда не считаютсяequal, даже если их текстовое содержимое совпадает.
Для equal равенство определяется рекурсивно; например, для двух cons-ячеек x и y (equal x y) возвращает t тогда и только тогда, когда оба приведённых ниже выражения возвращают t:
(equal (car x) (car y)) (equal (cdr x) (cdr y))
Таким образом, сравнение очень глубоко вложенных объектов может привести к глубокой рекурсии и вызвать ошибку.
- Функция: equal-including-properties object1 object2
-
Эта функция во всех случаях ведёт себя как
equal, но дополнительно требует, чтобы две строки для признания равными имели одинаковые текстовые свойства.(equal "asdf" (propertize "asdf" 'asdf t)) ⇒ t(equal-including-properties "asdf" (propertize "asdf" 'asdf t)) ⇒ nil
Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Equality-Predicates.html