【问题标题】:Testing throws from recursion递归测试抛出
【发布时间】:2015-02-19 15:21:09
【问题描述】:

我无法捕捉来自map 的第二次递归调用的抛出。 出于某种原因,来自(call-rec (first node)) 的异常冒泡,但不是来自(map call-rec node)

考虑以下示例:

    (deftest recursion-test
      (testing "Testing recursion throws" ;; => OK
        (is (thrown? Exception
                     (map #(throw (Exception. "e") [:a :b])))))

      (testing "Testing throws from recursion lvl 1" ;; => OK
        (is (thrown? 
             Exception
             (letfn [(call-rec [node]
                       (cond 
                        (vector? node)
                        (do
                          (throw (Exception. "e"))
                          (map call-rec node))
                        :else 
                        node))]
               (call-rec [:one :two])))))   

      (testing "Testing throws from map recursion lvl 2" ;; => FAILURE
        (is (thrown? Exception
                     (letfn [(call-rec [node]
                               (cond 
                                (vector? node)
                                (map call-rec node)

                                :else 
                                (throw (Exception. "e"))
                                ))]
                       (call-rec [:one :two])))))

      (testing "Testing throws from first recursion lvl 2" ;; => OK
        (is (thrown? Exception
                     (letfn [(call-rec [node]
                               (cond 
                                (vector? node)
                                (call-rec (first node))

                                :else 
                                (throw (Exception. "e"))
                                ))]
                       (call-rec [:one :two]))))))

【问题讨论】:

    标签: recursion clojure


    【解决方案1】:

    懒惰。表格

    (map call-rec node)
    

    创建一个永远不会实现的惰性序列,因此永远没有机会抛出异常。试试 Eager 版本:

    (mapv call-rec node)
    

    或者实现call-rec之外的序列使用:

    (doall (call-rec [:one :two]))
    

    【讨论】:

    • 另外值得一提的是代码中还有其他错误。例如(map #(throw (Exception. "e") [:a :b])) 应该是(map (fn [_](throw (Exception. "e"))) [:a :b])map 带有一个参数将在 Clojure 1.7 中创建映射转换器。
    猜你喜欢
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    • 2021-07-17
    • 1970-01-01
    相关资源
    最近更新 更多