2012-08-28 142 views
2
; common/math.clj 
(defn nths 
    "Returns a collection of values for each idx in idxs. Throws an error if any one idx is out of bounds." 
    [coll idxs] 
    (map #(nth coll %) idxs)) 

; nrepl 
common.math> (try (/ 1 0) 
    (catch Exception e (prn "in catch")) 
    (finally (prn "in finally"))) 
"in catch" 
"in finally" 
nil 
common.math> (try (nths '(5 6 7 8 9) '(0 5)) 
    (catch Exception e (prn "in catch")) 
    (finally (prn "in finally"))) 
"in finally" 
IndexOutOfBoundsException clojure.lang.RT.nthFrom (RT.java:784) 
common.math> (nths '(5 6 7 8 9) '(0 1 3)) 
(5 6 8) 
common.math> *clojure-version* 
{:major 1, :minor 5, :incremental 0, :qualifier "alpha4"} 

我無法弄清楚第二個expr有什麼問題。我期待它會重新打印:運行單元測試時出現異常未被捕獲的異種?

"in catch" 
"in finally" 

同樣的事情:

lein test unittest.common.math 

FAIL in (test-nths) (math.clj:87) 
expected: (thrown? IndexOutOfBoundsException (nths (quote (5 6 7 8 9)) (quote (0 5)))) 
    actual: nil 

應該通過。

回答

3

NTHS是懶惰的,所以當你的REPL嘗試打印結果的功能實際運行:

core> (def result (try (nths '(5 6 7 8 9) '(0 5)) 
         (catch Exception e (prn "in catch")) 
         (finally (prn "in finally")))) 
"in finally" 
#'core/result 
core> result 
; Evaluation aborted. 

您可以捕獲該異常在nths或更有意義抓它,當你使用它

rsadl.core> (def result (try (nths '(5 6 7 8 9) '(0 5)) 
         (catch Exception e (prn "in catch")) 
         (finally (prn "in finally")))) 
"in finally" 
#'core/result 
core> (try (println result) (catch Exception e (prn "in catch"))) 
("in catch" 
nil 

或number23_cn指出,只要您不需要爲了某種其他原因而懶惰,您就可以在創建時實現結果。

+0

有道理。我沒有想到repl會試圖評估'try'的返回值,也就是來自'(nths'(5 6 7 8 9)'(0 5))''的懶惰列表。 – wleung

+0

我稱之爲「懶蟲」,它以很多方式咬我...... ps:在技術上,REPL只是試圖打印這個值,它是懶惰的seq導致它被評估,然後 –

1
(try (doall (nths '(5 6 7 8 9) '(0 5))) 
    (catch Exception e (prn "in catch")) 
    (finally (prn "in finally"))) 
"in catch" 
"in finally" 
nil 
user=> 

因爲地圖返回lazy-seq?