Существует ли эквивалент конструкции Java switch
в Clojure? Если да, что это? Если нет, нам нужно использовать лестницу if
else
, чтобы достичь этого?
Явный эквивалент Java в Clojure?
Ответ 1
Попробуйте макрос case
:
(case (+ 2 3)
6 "error"
5 "ok")
или со значением по умолчанию
(case (+ 2 3)
5 "ok"
"error")
Помните, что согласно документации
Тестовые константы не оцениваются. Они должны быть компиляционными литералами, и их не нужно цитировать. (...)
См. дополнительные примеры в ClojureDocs.
Ответ 2
case является хорошим вариантом, как указал Ян
cond также очень полезен во многих связанных случаях, особенно если вы хотите перейти на основе оценки диапазона различных условных выражения, например
(defn account-message [balance]
(cond
(< balance 0) "Overdrawn!"
(< balance 100) "Low balance"
(> balance 1000000) "Rich as creosote"
:else "Good balance"))
Обратите внимание, что результат cond определяется первым совпадающим выражением, поэтому отрицательный баланс отображает "Overdrawn!" даже если он также соответствует случаю с низким балансом.
[Я редактировал код - удалил дополнительную скобку в конце, чтобы заставить ее работать]
Ответ 3
Хотя предложения @Jan и @mikera для использования case
или cond
(могу ли я добавить condp
в список?) являются звуковыми с точки зрения функционала¹ и хотя ограничения case
(например, тестовые значения могут быть только константами времени компиляции, возвращаемое значение по умолчанию является обязательным), зеркальное отражение от switch
, есть некоторые тонкие отличия:
-
case
не может использоваться с константами JavaEnum
; -
case
отправка основана на хэшировании AFAIK, что делает его сопоставимым с hashmaps с точки зрения производительности;switch
быстрее, -
вы не можете пройти через
case
, что означает, что вы должны использовать другие параметры (condp
с наборами значений?) для зеркалирования поведенияswitch
.
[¹] не работает, как в functional-programming, функциональный как при выполнении функции, служащей цели.