clojure - if-let语法

时间:2014-06-21 10:30:44

标签: clojure clojurescript

我正在尝试重构此代码以使用if-let

om/IWillMount
  (will-mount [_]
    (go (while true
          (if (om/get-state owner :is-loaded)
            (let [updated-world (<! (update-world (:dimensions opts) (:world @data)))]
              (om/transact! data #(assoc % :world updated-world))
              (swap! app-state assoc :world updated-world))
            (let [world (<! (get-world (:dimensions opts)))]
              (om/set-state! owner :is-loaded true)
              (om/transact! data #(assoc % :world world))
              (swap! app-state assoc :world world)))
          (<! (timeout (:poll-interval opts))))))

到目前为止,我已经尝试过这个:

om/IWillMount
  (will-mount [_]
    (go (while true
          (if-let [world (om/get-state owner :is-loaded)]
                    (<! (update-world (:dimensions opts) (:world @data)))
                    (<! (get-world (:dimensions opts)))
              (om/set-state! owner :is-loaded true)
              (om/transact! data #(assoc % :world world))
              (swap! app-state assoc :world world))
          (<! (timeout (:poll-interval opts))))))

但是我收到了这个错误:

  

引起:java.lang.IllegalArgumentException:if-let需要1或2   在web-game-of-life.app:58

中绑定载体后形成

2 个答案:

答案 0 :(得分:5)

if-let不适用......

if-let宏不适用于此处。在if-let中,绑定表单的结果用作测试。它压缩代码如

(let [world (get-world ...)]
   (if world
     (do-something-with world)
     (do-something-else)))
例如,如果get-world在没有检索到世界时返回nil,则

在您的案例中,您要测试的值与要绑定的值不同。您正在测试(om/get-state owner :is-loaded),但不会使用结果。

...但可以考虑重复代码

您的代码确实有重复,因此有一个保理机会。首先,将第一个绑定符号的相同代码更改为与第二个匹配,并将重复的行标记为。

          (if (om/get-state owner :is-loaded)
            (let [world (<! (update-world (:dimensions opts) (:world @data)))]
(1)           (om/transact! data #(assoc % :world world))
(2)           (swap! app-state assoc :world world))
            (let [world (<! (get-world (:dimensions opts)))]
              (om/set-state! owner :is-loaded true)
(1)           (om/transact! data #(assoc % :world world))
(2)           (swap! app-state assoc :world world)))

现在通过反转iflet

来考虑因素
(let [world (if (om/get-state owner :is-loaded) 
              (<! (update-world (:dimensions opts) (:world @data)))
              (do
                (om/set-state! owner :is-loaded true) 
                (<! (get-world (:dimensions opts)))))] 
  (om/transact! data #(assoc % :world world)) 
  (swap! app-state assoc :world world))

答案 1 :(得分:2)

if-let,与if一样,期望2或3个参数,如果条件为真,则计算第二个参数,如果条件为false,则计算可选的第三个参数。在这种情况下,您可以使用do来评估多个语句。

相关问题