- Вы (почти всегда) не должны использовать
def
внутри другого def
или defn
.Использование def
является глобальной декларацией, и оно (почти) всегда должно быть автономно в исходном файле.
См. Clojure для Brave & True для вступления онлайн илимного хороших книг, таких как Getting Clojure
.
Вы забыли про паренов вокруг
case
:
Пример:
(case args ...)
Использование
case
- это действительно специальная функция, предназначенная главным образом для взаимодействия объектов Java, с некоторыми серьезными ограничениями (иначе говоря, «оптимизация»).ИМХО почти всегда лучше использовать
cond
.
Пример:
(cond
(= :set-name args) (person (first args) age)
(= :set-age args) (person age)
...)
Обновление
Одна из проблем с case
является то, что это должен быть литерал времени компиляции .Тем не менее, это не очевидно, и нет никакого предупреждения, если вы пытаетесь использовать что-то, что не соответствует определению.Тогда вы просто получаете молчаливый сбой.Этот пример выглядит так, как будто он должен вернуть "my vec"
, но он не работает и возвращает "default"
:
; "The test-constants are not evaluated. They must be compile-time
; literals, and need not be quoted."
(let [myvec [1 2]]
(case myvec
[] "empty vec"
(vec '(1 2)) "my vec"
"default"))
;=> "default"
Таким образом, использование case
оставляет ловушку-ловушку, готовую разбить ваш код без предупреждения.