Next: Combining Conditions, Previous: Sequencing, Up: Control Structures [Contents][Index]
条件による制御構造は、候補の中から選択を行ないます。Emacs
Lispは4つの条件フォームをもちます。if
は他の言語のものとほとんど同じです。when
とunless
は、if
の変種です。cond
は一般化されたcase命令です。
if
は、conditionの値にもとづいて、then-formとelse-formsを選択します。評価されたconditionが非nil
の場合は、then-formが評価されて、その結果がreturnされます。それ以外は、else-formsがテキスト順に評価されて、最後のフォームの値がreturnされます(if
のelseパートは、暗黙のprogn
の例です。Sequencingを参照してください)。
conditionの値がnil
で、else-formsが与えられない場合、if
はnil
をreturnします。
選択されなかったブランチは決して評価されない — 無視される —
ので、if
はスペシャルフォームです。したがって、以下の例ではprint
は呼び出されることはないので、true
はプリントされません。
(if nil (print 'true) 'very-false) ⇒ very-false
これは、else-formsがなく、複数のthen-formsがあるかもしれない、if
の変種です。特に、
(when condition a b c)
は以下と完全に等価です
(if condition (progn a b c) nil)
これはthen-formがない、if
の変種です:
(unless condition a b c)
は以下と完全に等価です
(if condition nil a b c)
cond
は、任意の数の候補から選択を行ないます。cond
内の各clauseは、リストでなければなりません。このリストのCARはconditionで、(もしあれば)残りの要素はbody-formsです。したがって、条項は以下のようになります:
(condition body-forms…)
cond
は、各条項のconditionを評価することにより、テキスト順で条項を試験します。conditionの値が非nil
の場合、その条項は“成り立ち”ます。その後、cond
は、その条項のbody-formsを評価して、body-formsの最後の値をreturnします。残りの条項は無視されます。
conditionの値がnil
の場合、その条項は“成り立たず”、cond
は次の条項に移動して、その条項のconditionを試験します。
以下のようなものも、条項になります:
(condition)
conditionがテストされたときに非nil
なら、cond
フォームはconditionの値をreturnします。
すべてのconditionがnil
に評価された場合 —
つまりすべての条項が不成立の場合、cond
はnil
をreturnします。
以下の例は4つの条項をもち、x
の値が数字か、文字列化、バッファーか、シンボルかをテストします:
(cond ((numberp x) x) ((stringp x) x) ((bufferp x) (setq temporary-hack x) ; 1つの条項に (buffer-name x)) ; 複数bodyフォーム。 ((symbolp x) (symbol-value x)))
前の条項が不成立のとき、最後の条項を実行したいときがよくあります。これを行なうには、(t
body-forms)
のように、conditionの最後の条項にt
を使用します。フォームt
はt
に評価され、決してnil
にならないので、この条項が不成立になることはなく、最終的にcond
はこの条項に到達します。たとえば:
(setq a 5) (cond ((eq a 'hack) 'foo) (t "default")) ⇒ "default"
このcond
式は、a
の値がhack
の場合はfoo
、それ以外は文字列"default"
をreturnします。
任意の条件構成は、cond
かif
で表すことができます。したがって、どちらを選択するかは、スタイルの問題です、たとえば:
(if a b c) ≡ (cond (a b) (t c))
• Pattern matching case statement: |