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

3 clojure

我已经混淆了这段代码.

为什么这样做:

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

;..........
(my-func items) ; ok
Run Code Online (Sandbox Code Playgroud)

而这产生了一个例外:

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

    ;..........
    (my-func items) ; error
Run Code Online (Sandbox Code Playgroud)

是的

 Wrong number of args (0) passed to: PersistentArrayMap
Run Code Online (Sandbox Code Playgroud)

Jos*_*osh 10

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

(map (fn [x] ({:a x :b (:c x)})) '({:c "abc"}))
Run Code Online (Sandbox Code Playgroud)

这会产生你的错误.

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

(map (fn [x] {:a x :b (:c x)}) '({:c "abc"}))
;; ({:a {:c "abc"}, :b "abc"})
Run Code Online (Sandbox Code Playgroud)

这与尝试这样做的错误相同:

(defn func [x]
  ({:a x :b (:c x)}))
Run Code Online (Sandbox Code Playgroud)

实际上你想要的时候:

(defn func [x]
  {:a x :b (:c x)})
Run Code Online (Sandbox Code Playgroud)

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

({:a 1 :b 2} :b)
;; 2
Run Code Online (Sandbox Code Playgroud)

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

(:b {:a 1 :b 2})
;; 2
Run Code Online (Sandbox Code Playgroud)

所以我们也可以通过:b为正在创建的地图指定一个参数(在这种情况下)来消除错误,尽管它不会产生隐含的期望结果:

(map (fn [x] ({:a x :b (:c x)} :b)) '({:c "abc"}))
;; ("abc")
Run Code Online (Sandbox Code Playgroud)