Lisp勉強中(6) 分岐
最近仕事が終わるのが22時とか23時とかであんまり勉強が進まない。とはいえ今日は大事そうなところを覚えた。まあでも初期段階に覚えることって、大抵は大事なことだよね、言うまでもなく。
if
前回覚えた比較を使って分岐ができる。
(setq a 1) (if (= a 1) (print "aは1です") (print "aは1じゃない")) =>"aは1です" (setq a 2) (if (= a 1) (print "aは1です") (print "aは1じゃない")) =>"aは1じゃない"
うむ。(if 条件 trueの時 falseの時) みたいに書くのか。falseの時の記述は省略してもOK(もし条件がfalseだったら何もしない)。
when
whenという書き方もある。
(setq a 1) (when (= a 1) (print "a") (print "は") (print "1") (print "です") (print "!")) =>"a" =>"は" =>"1" =>"です" =>"!" =>"!" (setq a 2) (when (= a 1) (print "a") (print "は") (print "1") (print "です") (print "!")) =>nil
(when 条件 trueの時 trueの時 trueの時 ...) って書く。falseの時の動作は書けないけど、trueの時の動作を複数書ける。
出力される"!"が重複するのは、printで出力した"!"と評価結果が出力された"!"があるため。
unless
unlessはwhenの逆。
(setq a 1) (unless (= a 1) (print "a") (print "は") (print "1") (print "じゃない") (print "!")) =>nil (setq a 2) (unless (= a 1) (print "a") (print "は") (print "1") (print "じゃない") (print "!")) =>"a" =>"は" =>"1" =>"じゃない" =>"!" =>"!"
(unless 条件 falseの時 falseの時 falseの時 ...) って書く。条件がfalseの時の動作を複数書ける。
もちろん (when (not 条件) ...) で代用できそうだけど、スッキリ書ける方unlessの方が好きかも。
cond
こんなのもある。
(setq a 1) (cond ((= a 1) (print "aは") (print "1です") (print "!")) ((= a 2) (print "aは") (print "2です") (print "!")) ((= a 3) (print "aは") (print "3です") (print "!")) (t (print "aは") (print "なんだろう") (print "?"))) =>"aは" =>"1です" =>"!" =>"!" (setq a 5) (cond ((= a 1) (print "aは") (print "1です") (print "!")) ((= a 2) (print "aは") (print "2です") (print "!")) ((= a 3) (print "aは") (print "3です") (print "!")) (t (print "aは") (print "なんだろう") (print "?"))) =>"aは" =>"なんだろう" =>"?" =>"?"
これがcond。
(cond (条件1 条件1がtrueの時 条件1がtrueの時 ...) (条件2 条件2がtrueの時 条件2がtrueの時 ...) ...)
上から順に条件に合致するか調べて、合致したら条件の後ろを評価して抜ける。合致しなかったら条件の後ろは無視して次の条件を調べる。っていう感じ。複数に合致するような場合も、最初のやつしか評価されない。
最後まで合致しなかったらnilが返るらしい。ただ、上に書いたテストコードでは、最後の条件をtとしていて、必ず合致するようにしている。CやJavaのswitch文でいうdefault句みたいなことをするためにはこう書くわけか。
case
こっちの方がswitch文っぽい。
(setq a 1) (case a (1 (print "aは") (print "1です") (print "!")) (2 (print "aは") (print "2です") (print "!")) (3 (print "aは") (print "3です") (print "!")) (otherwise (print "aは") (print "なんだろう") (print "?"))) =>"aは" =>"1です" =>"!" =>"!" (setq a 5) (case a (1 (print "aは") (print "1です") (print "!")) (2 (print "aは") (print "2です") (print "!")) (3 (print "aは") (print "3です") (print "!")) (otherwise (print "aは") (print "なんだろう") (print "?"))) =>"aは" =>"なんだろう" =>"?" =>"?"
otherwiseってなんか長いなあ。
使い分け
これらはうまく使い分けできそう。
- trueのときとfalseのときでやりたいことがあるならif
- trueのときだけでいいならwhen
- falseのときだけでいいならunless
- いろいろ調べたいならcond
- ひとつの変数について色々調べたいならcase
こんな感じかな。実際にコード書いて見たらこの辺は変わってくる可能性もあるけど。