TL;DR

  • Clojure の条件分岐には if、when、cond、case がある。if で複数の式を実行するには do でまとめる。
  • 複数の条件を調べるときは、if を入れ子にせず cond を使う。case は、どの値にも一致しないと例外を投げる。

内容

if

Clojure では次のように書く。

(let [a 5]
  (if (> a 0)
    (println a "is positive")))
;; 5 is positive

if の第 1 引数に条件を、第 2 引数に条件を満たすときに実行する式を渡す。そして、第 3 引数に条件を満たさないときに実行する式を渡す。

(let [a -5]
  (if (> a 0)
    (println a "is positive")
    (println a "is negative")))

他の言語の else if を実現するには、次のように if を入れ子にする。ただし、可読性が悪いので、この場合は cond を使うのがよい。

(let [a 0]
  (if (> a 0)
    (println a "is positive")
    (if (< a 0)
      (println a "is negative")
      (println a "is neither positive nor negative"))))

条件を満たしたときに複数の式を実行したいときは、do でまとめる必要がある。

(let [a 5]
  (if (> a 0)
    (do
      (println a "is positive")
      (println "There are infinite positive numbers"))
 
    (do
      (println a "is negative")
      (println "There are infinite negative numbers"))))

when

if と似ているが、when では条件が true のときの挙動だけを指定できる。false のときは nil が返る。また、do を使わなくても複数の式を実行できる。

(let [print-something true]
  (when print-something
    (println "I print something.")
    (println "I print other things too.")))
 
(let [print-something false]
  (when print-something
    (println "I print something.")
    (println "I print other things too.")))

cond

複数の条件を調べるときは、if を入れ子にするのではなく、cond を使うのが一般的である。

(let [number 5]
  (cond
    (> number 0) (println number "is positive")
    (< number 0) (println number "is negative")
    :else (println number "is neither positive nor negative")))

:else にはどの条件も満たさないときに実行する式を指定する。処理が必要なければ省略できる。

case

引数を一連の値と比べ、一致した値の式を実行する。

(let [num 20]
  (case num
    1 "one"
    2 "two"
    3 "three"
    4 "four"
    5 "five"
    "I don't know that number"))

一番最後の式は、どの値にも一致しないときに実行される。cond と違い、どの値にも一致しないときは例外を投げる。

(let [num 20]
  (case num
    1 "one"
    2 "two"
    3 "three"
    4 "four"
    5 "five"))
;; java.lang.IllegalArgumentException: No matching

キーワード