web-dev-qa-db-ja.com

Clojureで同等のJavaのスイッチ?

ClojureにJavaのswitchコンストラクトに相当するものはありますか?はいの場合、それは何ですか?いいえの場合、それを実現するためにifelseラダーを使用する必要がありますか?

31
vikbehal

caseマクロを試してください。

(case (+ 2 3)
  6 "error"
  5 "ok")

またはデフォルト値で

(case (+ 2 3)
  5 "ok"
  "error")

ドキュメントによると覚えておいてください

テスト定数は評価されません。それらはコンパイル時リテラルでなければならず、引用符で囲む必要はありません。 (...)

ClojureDocs で他の例を参照してください。

34
Jan

case Janが指摘したように、良いオプションです

cond は、関連する多くの状況で非常に役立ちます。特に、さまざまな条件式の評価に基づいて切り替える場合は特に便利です。

(defn account-message [balance]
  (cond 
    (< balance 0) "Overdrawn!"
    (< balance 100) "Low balance"
    (> balance 1000000) "Rich as creosote"
    :else "Good balance"))

Condの結果は最初の一致する式によって決定されるため、負のバランスでは「Overdrawn!」と表示されることに注意してください。ローバランスの場合にもマッチしますが。

[コードを編集しました-動作させるために最後の余分なブラケットを削除しました]

39
mikera

@Janと@mikeraの使用提案 case または cond (追加してもよい condp リストに?)は機能的¹の観点からは健全であり、caseの制限(たとえば、テスト値はコンパイル時定数のみであり、デフォルトの戻り値は必須です)はswitchいくつかの微妙な違いがあります:

  • caseはJava Enum定数;

  • caseのディスパッチは、パフォーマンスの点でハッシュマップに匹敵するハッシュAFAIKに基づいています。 switchははるかに高速です;

  • caseでフォールスルーすることはできません。つまり、condpの動作を反映するには、他のオプション(switchと値セット?)を使用する必要があります。


[¹] functional-programming のように機能せず、機能を実行するように機能し、目的を果たします。

7
omiel