Используйте equal? для сравнения содержимого списков и векторов, а eq? — чтобы проверить, ссылаются ли значения на один объект. Для чисел используйте =.
Совпадение содержимого называется равенством, а совпадение объекта называется идентичностью объекта.
Сравните два списка
Вставьте пример в песочницу и запустите его.
(define xs (list 1 2))
(define same xs)
(define other (list 1 2))
(list (equal? xs other) (eq? xs other) (eq? xs same))Результат
(#t #f #t)xs и other ссылаются на отдельно созданные списки. Элементы совпадают, поэтому equal? возвращает #t. Объекты разные, поэтому eq? возвращает #f.
same ссылается на список, уже хранящийся в xs. Их сравнение через eq? даёт #t. Идентичность объекта означает, что обе ссылки ведут к одному и тому же объекту.
Сравните числа
(list (= 2 2.0) (eqv? 2 2.0) (equal? (list 1 2) (list 1 2)))Результат
(#t #f #t)= считает точное 2 и неточное 2.0 одним и тем же математическим числом. eqv? различает точные и неточные числа, поэтому возвращает #f.
equal? тоже различает точные и неточные числа, в том числе внутри списков. Последнее сравнение даёт #t, потому что оба списка содержат одинаковые точные целые числа.
Выберите сравнение
Предикат — это процедура, которая отвечает на вопрос значением #t или #f.
| Предикат | Что сравнивает |
|---|---|
= | математические значения чисел; другие типы вызывают ошибку |
eq? / eqv? | значения атомов с учётом точности чисел; идентичность составных объектов |
equal? | содержимое пар, векторов, байтовых векторов и строк, включая вложенные значения |
== / != | equal? / результат, противоположный equal? |
Здесь атомами называются числа, знаки, булевы значения, символы и пустой список. В текущем профиле языка eq? и eqv? дают одинаковый результат.
equal? обнаруживает циклы при сравнении вложенных значений. Поэтому сравнение завершается, даже если структура ссылается на саму себя. Процедуры сравниваются по идентичности объекта, в том числе через equal?; их тела не сравниваются.
Связанные страницы
Раздел Данные и составные значения поможет выбрать нужный вид значения. В разделе Процедуры списков и составных значений показано, как создавать значения и менять содержимое вектора.