Когда это нужно
Выбирайте равенство по смыслу. Для чисел подходит математическое равенство, для атомов или того же составного объекта равенство по идентичности, а для структур данных глубокое равенство.
Проверьте запуском
LISPEX
(list (= 2 2.0) (eqv? 2 2.0) (equal? (list 1 2) (list 1 2)))Наблюдаемый результат
OUTPUT
(#t #f #t)Разбор примера
= считает точное 2 и неточное 2.0 одним и тем же математическим числом. eqv? сохраняет различие в точности. Два отдельно созданных списка остаются разными объектами, но equal? видит одинаковое содержимое.
Как рассуждать
- В этом профиле
eq?иeqv?совпадают на атомах и сравнивают составные значения по идентичности. eqv?иequal?чувствительны к точности, поэтому точное2и неточное2.0различаются.equal?рекурсивно сравнивает пары, векторы, байтовые векторы и строки с обнаружением циклов.
Быстрый выбор
| Предикат | Назначение | Поведение для агрегатов |
|---|---|---|
= | математическое равенство чисел | нечисло даёт ошибку области |
eq? | атомы и идентичность объекта | истина только для того же объекта |
eqv? | атомы с учётом точности и идентичность | истина только для того же объекта |
equal? | содержимое вложенных данных | рекурсивное сравнение с защитой от циклов |
== / != | читаемые структурные псевдонимы | equal? и его отрицание |
Частая ошибка
= принимает только числа. == и != это структурные псевдонимы.
Текущие границы
- Равенство процедур никогда не сравнивает их тела структурно.
Куда дальше
Виды значений и их идентичность описаны в главе о данных, а операции, создающие отдельные объекты, собраны в справочнике агрегатов.