错误的args(0)传递给:PersistentArrayMap for" map"

时间:2016-08-19 01:06:23

标签: clojure

我对这段代码进行了混淆。

为什么这样做:

(let [
   items [{:var1 x, :var2  x, :var3 (:something x), :var4 (:something2 x)}]

;..........
(my-func items) ; ok

然而这产生了一个例外:

(let [
   items (map (fn [x] ({:var1 x, :var2 x, :var3 (:something x), :var4 (:something2 x)})) (db/get-items-from-db))

    ;..........
    (my-func items) ; error

 Wrong number of args (0) passed to: PersistentArrayMap

1 个答案:

答案 0 :(得分:9)

当我们将它剥离到骨头时,我们有:

(map (fn [x] ({:a x :b (:c x)})) '({:c "abc"}))

会产生错误。

问题是地图定义周围有括号,因此,地图被视为一个函数,在这种情况下没有赋予它的参数。删除parens,它的工作原理:

(map (fn [x] {:a x :b (:c x)}) '({:c "abc"}))
;; ({:a {:c "abc"}, :b "abc"})

尝试这样做会出现同样的错误:

(defn func [x]
  ({:a x :b (:c x)}))

事实上你想要:

(defn func [x]
  {:a x :b (:c x)})

如果我们记得地图可以用作函数,并且参数指定要返回的键值,则可能有助于进一步理解:

({:a 1 :b 2} :b)
;; 2

虽然我们经常反过来并使用密钥作为函数:

(:b {:a 1 :b 2})
;; 2

因此我们也可以通过为正在创建的地图指定一个参数(在本例中为:b)来删除错误,但它不会产生隐含的预期结果:

(map (fn [x] ({:a x :b (:c x)} :b)) '({:c "abc"}))
;; ("abc")