2016-12-20 9 views
0

У меня естьИзменение значения атома вектора с помощью свопа

(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 "[email protected]"]

Я не знаю, что означает эта ошибка ни как разрешить его

ответ

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

создает анонимную функцию с одним параметром, поэтому она не является ошибкой, но не выполняет своп до выполнения. Если вы попытаетесь выполнить его, вы получите сообщение об ошибке, так как swap! ожидает, что первым параметром будет атом, а не карта.

Похоже, что вы хотите:

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

или просто

(swap! a replace-value) 
+0

'(своп ! replace-value) 'работает в repl, но когда я использую его кнопкой, например' [: input.btn.btn-primary {: type: button : on-click (swap! tdata replace-value) : значение «Изменить»}] 'ничего не делает – rbb

0

Как ответил Ли, кажется, что то, что вы хотите В Ваш комментарий (обмен данными заменить значение!) ответа Ли,

Я думаю, вы неправильно поняли особые формы clojure,

#(...) 

представляет собой сокращенную

(fn [arg1 arg2 ...] (...)) 

В соответствии с swap!, второй из 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 заменить значение): значение «Изменить»}] он ничего

:on-click принимает функцию не делать, так что вы должны добавить # до его значения, как этот

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