당신은 자바에 더 가깝게 뭔가를 할 수 있습니다. 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))))
추가 조항이 시도 - 캐치에 그것을 포장으로 이어질 때 :
(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' 주위에 또 다른'try' 폼을 추가해야만 리소스를 열거 나 사용할 때 던져지는 예외를 잡을 수 있습니다.하지만 try/catch 로직과는 별도로 열기/닫기 자동화를 처리하는 것은 아닙니다. 나쁜 것. Java 구조와 1 : 1의 동등성을 기대하고 있었지만 실제로 그렇게해야 할 이유는 없습니다. – DaoWen
'(try ...)'블록 안에'(catch exceptions e ...)'와'(finally (.close r))'를 둘 수 있지만'with-resource' 매크로는 지원하지 않습니다 그것은 기본적으로 당신이 직접 작성해야합니다. – erdos
@DaoWen 1 : 1 등가물입니다. 'try (Foo x = bar()) {...}'는'bar()'를 호출하는 동안 발생한 예외를 처리하지 않습니다. 어떻게 그럴 수 있니? 유효한'x'는'.close()'를 호출 할 범위에 없습니다. – amalloy