使用swap

时间:2016-12-20 15:55:03

标签: clojure clojurescript

我有

(def data {:headers ["A" "B" "C" "D"]
                 :rows [["1" "2" "3" "4"] ["5" "6" "7" "8"] ["9" "10" "11" "12"]]})

我有一个功能

(defn replace-value [struct] 
    (clojure.walk/prewalk-replace {"3" "hello"} (struct :rows)))

当我这样做时

(replace-value @data) > [["1" "2" "hello" "4"] ["5" "6" "7" "8"] ["9" "10" "11" "12"]]

我得到了我的期望。

但是,我希望使用swap!来实现相同的结果所以我尝试了

#(swap! data (replace-value %))

但我收到错误#object[user$eval1308$fn__1309 0x6caeefd7 "user$eval1308$fn__1309@6caeefd7"]

我不知道这个错误意味着什么,也不知道如何解决它

2 个答案:

答案 0 :(得分:1)

#(swap! data (replace-value %))

使用一个参数创建一个匿名函数,因此它不是错误,但在执行之前不会执行交换。如果您尝试执行它,您将收到错误,因为swap!期望第一个参数是原子而不是地图。

看起来你想要:

(def a (atom data))
(swap! a #(replace-value %))

或只是

(swap! a replace-value)

答案 1 :(得分:0)

李回答说,看起来像你想要的     (交换!数据替换值) 在你对李的回答的评论中,

我认为你误解了clojure的特殊形式,

#(...)

的简写
(fn [arg1 arg2 ...] (...))

根据https://blog.risingstack.com/node-hero-node-js-authentication-passport-js/swap!中的第二个应该是一个函数。所以你的代码

#(swap! data (replace-value %))

实际上意味着

(fn [swap-input] (swap! data (replace swap-input)))

%是参数的缩写(如果有多个参数,您可以使用%1%2等。

要解决此问题,您可以将其更改为

`#(swap! data replace-value)`

`(fn [] (swap! data #(replace-value %))`

还有李的评论中的问题

  

当我在一个按钮中使用它时,例如[:input.btn.btn-primary {:type:button:on-click(swap!tdata replace-value):value" Change"}] it什么都不做

:on-click接受一个函数,因此您应该在其值之前添加#,如下所示

:on-click #(swap! data replace-value)