2.7 Предикаты типов

Сам интерпретатор Emacs Lisp не выполняет проверку типов фактических аргументов, передаваемых функциям при их вызове. Он не может этого делать, поскольку аргументы функций в Lisp не имеют объявленных типов данных, в отличие от других языков программирования. Поэтому каждая отдельная функция должна сама проверять, принадлежит ли каждый фактический аргумент типу, который функция может использовать.

Все встроенные функции проверяют типы своих фактических аргументов, когда это уместно, и выдают ошибку wrong-type-argument, если аргумент имеет неверный тип. Например, вот что происходит, если передать аргумент функции +, который она не может обработать:

(+ 2 'a)
     error→ Wrong type argument: number-or-marker-p, a

Если вы хотите, чтобы ваша программа обрабатывала разные типы по-разному, вы должны выполнять явную проверку типов. Самый распространённый способ проверить тип объекта — вызвать функцию предикат типа. В Emacs есть предикат типа для каждого типа, а также некоторые предикаты для комбинаций типов.

Функция-предикат типа принимает один аргумент; она возвращает t, если аргумент принадлежит соответствующему типу, и nil в противном случае. Следуя общему соглашению Lisp для функций-предикатов, имена большинства предикатов типов заканчиваются на «p».

Вот пример, в котором используются предикаты listp для проверки на список и symbolp для проверки на символ.

(defun add-on (x)
  (cond ((symbolp x)
         ;; Если X — символ, поместить его в LIST.
         (setq list (cons x list)))
        ((listp x)
         ;; Если X — список, добавить его элементы в LIST.
         (setq list (append x list)))
        (t
         ;; Мы обрабатываем только символы и списки.
         (error "Invalid argument %s in add-on" x))))

Ниже приведена таблица предопределённых предикатов типов в алфавитном порядке со ссылками на дополнительную информацию.

atom

См. atom.

arrayp

См. arrayp.

bignump

См. bignump.

bool-vector-p

См. bool-vector-p.

booleanp

См. booleanp.

bufferp

См. bufferp.

byte-code-function-p

См. byte-code-function-p.

case-table-p

См. case-table-p.

char-or-string-p

См. char-or-string-p.

char-table-p

См. char-table-p.

closurep

См. closurep.

commandp

См. commandp.

compiled-function-p

См. compiled-function-p.

condition-variable-p

См. condition-variable-p.

consp

См. consp.

custom-variable-p

См. custom-variable-p.

fixnump

См. fixnump.

floatp

См. floatp.

fontp

См. Низкоуровневое представление шрифтов.

frame-configuration-p

См. frame-configuration-p.

frame-live-p

См. frame-live-p.

framep

См. framep.

functionp

См. functionp.

hash-table-p

См. hash-table-p.

integer-or-marker-p

См. integer-or-marker-p.

integerp

См. integerp.

interpreted-function-p

См. interpreted-function-p.

keymapp

См. keymapp.

keywordp

См. Переменные, которые никогда не изменяются.

listp

См. listp.

markerp

См. markerp.

mutexp

См. mutexp.

nlistp

См. nlistp.

number-or-marker-p

См. number-or-marker-p.

numberp

См. numberp.

obarrayp

См. obarrayp.

overlayp

См. overlayp.

processp

См. processp.

recordp

См. recordp.

sequencep

См. sequencep.

string-or-null-p

См. string-or-null-p.

stringp

См. stringp.

subrp

См. subrp.

symbolp

См. symbolp.

syntax-table-p

См. syntax-table-p.

threadp

См. threadp.

vectorp

См. vectorp.

wholenump

См. wholenump.

window-configuration-p

См. window-configuration-p.

window-live-p

См. window-live-p.

windowp

См. windowp.

Наиболее общий способ проверить тип объекта — вызвать функцию type-of. Напомним, что каждый объект принадлежит одному и только одному примитивному типу; type-of сообщает, какому именно (см. Типы данных Lisp). Но type-of ничего не знает о непримитивных типах. В большинстве случаев предпочтительнее использовать предикаты типов, а не type-of.

Функция: type-of object

Эта функция возвращает символ, именующий примитивный тип object. Возвращаемое значение — один из символов bool-vector, buffer, char-table, compiled-function, condition-variable, cons, finalizer, float, font-entity, font-object, font-spec, frame, hash-table, integer, marker, mutex, obarray, overlay, process, string, subr, symbol, thread, vector, window или window-configuration. Однако если object является записью (record), возвращается тип, заданный её первым полем; см. Записи.

(type-of 1)
     ⇒ integer
(type-of 'nil)
     ⇒ symbol
(type-of '())    ; () — это nil.
     ⇒ symbol
(type-of '(x))
     ⇒ cons
(type-of (record 'foo))
     ⇒ foo
Функция: cl-type-of object

Эта функция возвращает символ, именующий тип object. Обычно она ведёт себя как type-of, за исключением того, что гарантирует возврат наиболее точного возможного типа, что также означает, что конкретный возвращаемый тип может меняться в зависимости от версии Emacs. По этой причине, как правило, никогда не следует сравнивать её возвращаемое значение с каким-либо фиксированным набором типов.

(cl-type-of 1)
     ⇒ fixnum
(cl-type-of 'nil)
     ⇒ null
(cl-type-of (record 'foo))
     ⇒ foo