异常后获取部分地图结果

时间:2016-10-18 06:33:37

标签: clojure

在执行期间发生异常时,如何从地图中获取部分结果?

(let [numbers [3 3 0 3]
  results (map #(/ 3 %) numbers)]
 results)

并返回:

[3 3]

4 个答案:

答案 0 :(得分:4)

例如:

(let [numbers [3 3 0 3]
      results (map
               #(try (/ 3 %)
                     (catch Exception e e))
                   numbers)]
  (take-while #(not (instance? Exception %)) results))

答案 1 :(得分:3)

由于抛出的异常会将堆栈展开到捕获到异常的位置(在您的情况下它会升至顶层),因此您无法在result之后运行if。你可以做的是手动将一些值放在错误被捕获的地方:

(let [numbers [3 3 0 3]
      results (take-while number?
                          (map #(try
                                  (/ 3 %)
                                  (catch Throwable ex :error))
                               numbers))]
  results)

答案 2 :(得分:2)

以下是使用cats库的exception monad的方法:

(ns your-project.core
  (:require [cats.monad.exception :as e]))

(let [numbers [3 3 0 3]
      results (->> numbers
                   (map #(e/try-on (/ 3 %))) ; wrap division result in a try
                   (take-while e/success?)   ; take values while successful
                   (mapv e/extract))]        ; unwrap the values from the trys
  results)

;; => [1 1]

如果你想保留异常后的值:

(let [numbers [3 3 0 3]
      results (->> numbers
                   (map #(e/try-on (/ 3 %)))
                   (filter e/success?)       ; filter all successful values
                   (mapv e/extract))]
  results)

;; => [1 1 1]

答案 3 :(得分:1)

使用keep

(let [numbers [3 3 0 3]]
  (keep #(try 
          (/ 3 %)
          (catch RuntimeException _ nil)) numbers))