Я возился с картами Clojure, и я обнаружил эту ситуацию, которую я не могу понять.Исключение с использованием картографических и анонимных функций в Clojure
Скажем, у меня есть карта, как это:
(def map-test {:name "head" :size 3})
Я хочу, чтобы изменить значение этой карты, в Clojure обычным способом является создание нового с измененными данными.
Так что я эту функцию:
(defn map-change
[part]
{:name (str (:name part) "-" 1) :size (:size part)})
Как и ожидалось призыванием (map-change map-test)
возвращается: {:name "head-1", :size 3}
Так что я написал эту функцию с помощью map
клонировать хэш-карту в заданное число раз, как это {:name "head-1" ...}{:name "head-2" ...}{:name "head-3" ...}
и т.д.:
(defn repeat-test
[part times]
(map #({:name (str (:name part) "-" %) :size (:size part)}) (range 1 (inc times))))
Но я получил исключение, которое я не могу понять, когда Я называю (repeat-test map-test 5)
:
Wrong number of args (0) passed to: PersistentArrayMap
отладчик выдает это исключение, когда присвоения значения :size
сразу после оценивала (:size part)=>3
Вот последняя часть StackTrace:
Unhandled clojure.lang.ArityException
Wrong number of args (0) passed to: PersistentArrayMap
AFn.java: 429 clojure.lang.AFn/throwArity
AFn.java: 28 clojure.lang.AFn/invoke
REPL: 80 clj-lab-00.hobbits/repeat-test/fn
core.clj: 2644 clojure.core/map/fn
LazySeq.java: 40 clojure.lang.LazySeq/sval
LazySeq.java: 49 clojure.lang.LazySeq/seq
RT.java: 521 clojure.lang.RT/seq
core.clj: 137 clojure.core/seq
core_print.clj: 46 clojure.core/print-sequential
core_print.clj: 153 clojure.core/fn
core_print.clj: 153 clojure.core/fn
MultiFn.java: 233 clojure.lang.MultiFn/invoke
core.clj: 3572 clojure.core/pr-on
core.clj: 3575 clojure.core/pr
core.clj: 3575 clojure.core/pr
AFn.java: 154 clojure.lang.AFn/applyToHelper
....
Но если я использую не анонимную функцию, которая выполняет ту же операцию, что и анонимная:
(defn map-change
[part i]
{:name (str (:name part) "-" i) :size (:size part)})
(defn repeat-test
[part times]
(map #(map-change part %1) (range 1 (inc times))))
Теперь вызывается (repeat-test map-test 5)
работ. Зачем ? Что мне не хватает?
Я бы добавил '# (do {: a%})' в качестве опции. – OlegTheCat
Итак, правило для новичков - использовать '(fn [x] ...)' и избегать формы '#(), по крайней мере, до тех пор, пока я не пойму макросы лучше. – Marcs
@OlegTheCat Это тоже возможность. Я добавил. Есть еще много опций: '# (и {: a%})', '# (или {: a%})' :-). @Marcs Я думаю, что это хорошее эмпирическое правило. Еще одно замечание: анонимные литералы функций не могут быть вложенными. –