Spec-Zone.ru › Elisp

Условные операторы

Условные управляющие структуры выбирают между альтернативами. В Emacs Lisp есть пять условных форм: if, которая очень похожа на другие языки; when и unless, которые являются вариантами if; cond, которая является обобщенной инструкцией case; и pcase, которая является обобщением cond (см. Условные операторы с сопоставлением шаблонов).

Специальная форма: if условие тогда-форма иначе-формы…

if выбирает между тогда-форма и иначе-формами на основе значения условия. Если вычисленное условие не nil, тогда-форма вычисляется и возвращается результат. В противном случае иначе-формы вычисляются в текстовом порядке, и возвращается значение последней из них. (Часть иначе в if является примером неявного progn. См. Последовательность.)

Если условие имеет значение nil, и иначе-форм не задано, if возвращает nil.

if является специальной формой, потому что ветвь, которая не выбрана, никогда не вычисляется — она игнорируется. Таким образом, в этом примере true не выводится, потому что print никогда не вызывается:

(if nil
    (print 'true)
  'very-false)
⇒ very-false
Макрос: when условие тогда-формы…

Это вариант if, где нет иначе-форм, и, возможно, несколько тогда-форм. В частности,

(when condition a b c)

полностью эквивалентно

(if condition (progn a b c) nil)
Макрос: unless условие формы…

Это вариант if, где нет тогда-формы:

(unless condition a b c)

полностью эквивалентно

(if condition nil
   a b c)
Специальная форма: cond оператор…

cond выбирает между произвольным количеством альтернатив. Каждый оператор в cond должен быть списком. CAR этого списка является условием; оставшиеся элементы, если таковые имеются, являются тело-формами. Таким образом, оператор выглядит так:

(condition body-forms…)

cond пытается выполнить операторы в текстовом порядке, вычисляя условие каждого оператора. Если значение условия не nil, оператор успешен; затем cond вычисляет его тело-формы и возвращает значение последней из тело-форм. Все оставшиеся операторы игнорируются.

Если значение условия nil, оператор терпит неудачу, и cond переходит к следующему оператору, пытаясь выполнить его условие.

Оператор также может выглядеть так:

(condition)

Тогда, если условие не nil при проверке, форма cond возвращает значение условия.

Если все условия вычисляются как nil, так что все операторы терпят неудачу, cond возвращает nil.

Следующий пример имеет четыре оператора, которые проверяют случаи, когда значение x является числом, строкой, буфером и символом соответственно:

(cond ((numberp x) x)
      ((stringp x) x)
      ((bufferp x)
       (setq temporary-hack x) ; multiple body-forms
       (buffer-name x))        ; in one clause
      ((symbolp x) (symbol-value x)))

Часто мы хотим выполнить последний оператор всякий раз, когда ни один из предыдущих операторов не был успешным. Для этого мы используем t в качестве условия последнего оператора, например: (t body-forms). Форма t вычисляется как t, что никогда не nil, поэтому этот оператор никогда не терпит неудачу, при условии, что cond до него доходит. Например:

(setq a 5)
(cond ((eq a 'hack) 'foo)
      (t "default"))
⇒ "default"

Это выражение cond возвращает foo если значение a hack, и возвращает строку "default" в противном случае.

Любую условную конструкцию можно выразить с помощью cond или с помощью if. Поэтому выбор между ними зависит от стиля. Например:

(if a b c)
≡
(cond (a b) (t c))

Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Conditionals.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API