2016-10-18 2 views

ответ

4

Например:

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

поскольку выброшенное исключение раскручивается стек до того места, где ловится исключение (в вашем случае он поднимается до верхнего уровня), вы не можете работать с result после этого. Что вы можете сделать, чтобы вручную поместить некоторое значение, где был пойман ошибка:

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

Я бы заменил «Throwable» на «Exception» здесь. Обычно подавление Java ['Error'] (http://docs.oracle.com/javase/7/docs/api/java/lang/Error.html) не является хорошей идеей. – OlegTheCat

+0

'ex' ->' _' ... – OlegTheCat

1

Использование keep:

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

Вот подход, использующий exception монады в cats библиотеки:

(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] 
Смежные вопросы