首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Clojure中尝试使用资源

在Clojure中尝试使用资源
EN

Stack Overflow用户
提问于 2017-10-10 15:54:07
回答 2查看 1.8K关注 0票数 8

Clojure是否具有与Java的试着用资源构造相当的内容?

如果不是,在Clojure代码中处理这个成语的正常方法是什么?

用于安全地打开和关闭资源的前Java-7成语非常冗长,以至于他们实际上向语言中添加了对试用资源的支持。在我看来,奇怪的是,我在标准Clojure库中找不到这个用例的宏。

一个基于Clojure的主流项目存储库的例子--展示如何在实践中处理这个问题--将非常有帮助。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-10 16:01:11

您可以使用开着将资源绑定到符号,并确保在控件流离开块后资源被关闭。

下面的示例来自clojuredocs。

代码语言:javascript
复制
(with-open [r (clojure.java.io/input-stream "myfile.txt")] 
     (loop [c (.read r)] 
       (when (not= c -1)
         (print (char c)) 
         (recur (.read r)))))

这一范围将扩大到以下方面:

代码语言:javascript
复制
(let [r (clojure.java.io/input-stream "myfile.txt")] 
  (try
    (loop [c (.read r)] 
      (when (not= c -1)
        (print (char c)) 
        (recur (.read r))))
    (finally (.close r))))

您可以看到,let块是使用调用.close()方法的try-finally创建的。

票数 13
EN

Stack Overflow用户

发布于 2017-10-10 21:13:53

您可以做一些与java更接近的事情,在with-open之上构建一些宏。看起来可能是这样的:

代码语言:javascript
复制
(defmacro with-open+ [[var-name resource & clauses] & body]
  (if (seq clauses)
    `(try (with-open [~var-name ~resource] ~@body)
          ~@clauses)
    `(with-open [~var-name ~resource] ~@body)))

因此,您可以在绑定的同时传递附加子句。

代码语言:javascript
复制
(with-open+ [x 111]
  (println "body"))

扩展为简单的with-open

代码语言:javascript
复制
(let*
  [x 111]
  (try (do (println "body")) (finally (. x clojure.core/close))))

而附加的子句则导致尝试捕获中的it包装:

代码语言:javascript
复制
(with-open+ [x 111
             (catch RuntimeException ex (println ex))
             (finally (println "finally!"))]
  (println "body"))

扩展到

代码语言:javascript
复制
(try
  (let*
    [x 111]
    (try (do (println "body")) (finally (. x clojure.core/close))))
  (catch RuntimeException ex (println ex))
  (finally (println "finally!")))

但这仍然是一种固执己见的解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46670958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档