Javaの近くでは、with-open
の上にマクロを作成することができます。
(defmacro with-open+ [[var-name resource & clauses] & body]
(if (seq clauses)
`(try (with-open [~var-name ~resource] [email protected])
[email protected])
`(with-open [~var-name ~resource] [email protected])))
このように、バインディングの横に追加の句を渡すことができます。
(with-open+ [x 111]
(println "body"))
は、単純なwith-open
に展開:
(let*
[x 111]
(try (do (println "body")) (finally (. x clojure.core/close))))
追加条項はのtry-catchでラップにつながるながら:
(with-open+ [x 111
(catch RuntimeException ex (println ex))
(finally (println "finally!"))]
(println "body"))
は
(try
(let*
[x 111]
(try (do (println "body")) (finally (. x clojure.core/close))))
(catch RuntimeException ex (println ex))
(finally (println "finally!")))
しかし、まだに展開しますそれはかなりの意見ですソリューション。
これは意味があります。私はまだ開いているまたはリソースを使用している間にスローされた例外をキャッチするために、 'with-open'の周りにもう1つの' try'フォームを追加する必要がありますが、try/catchロジックとは別にオープン/悪いこと。私はJavaのコンストラクタと1対1の同等性を期待していましたが、実際にはそれを期待する必要はありません。 – DaoWen
あなたは '(try ...)'ブロックの中に '(Exception e ... catch ')と'(finally(.close r)) 'を持つことができますが、' with-resource'マクロはそれはあなたがそれをあなた自身で書く必要があるので、デフォルトでです。 – erdos
@DaoWen 1:1の等価です。 'try(Foo x = bar()){...}'は 'bar()'の呼び出し中に発生した例外を処理しません。どうした?スコープに '.close()'を呼び出す有効な 'x'はありません。 – amalloy