Clojure:try,catch 宏,它也关闭任何文件流(不是打开) [英] Clojure: try, catch macro that also closes any filestreams (not with-open)

查看:13
本文介绍了Clojure:try,catch 宏,它也关闭任何文件流(不是打开)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

感谢到目前为止的所有帮助.这是我的新代码,它有效.但并不完全符合我的意愿.
我需要它来返回 java 异常(不要问我为什么).示例:

Thanks for all the help so far. This is my new code, which works. But not exactly as I would like it to.
I need it to return the java exception (don't ask me why). Example:

(安全 (/1 0))
#<ArithmeticException java.lang.ArithmeticException: 除以零>

这就是我想要的样子.但是当我使用处理绑定等的其他代码子句时,我得到了 Clojure 异常:

(safe (/ 1 0))
#<ArithmeticException java.lang.ArithmeticException: Divide by zero>

which is how I want it to be. But when I make use of the other clauses of code that handle bindings etc, I get the Clojure exception:

(seefe [f(FileReader.(File. "C:/txtf.txt"))](. f read))
FileNotFoundException C:	xtf.txt (The system cannot find the file specified)  java.io.FileInputStream.open (:-2)

我可以做些什么来防止这种情况,并改为显示 Java 异常?

What can I do to prevent this, and show the Java exception instead?

(defmacro safe [bindings & code]
  (if (list? bindings)
    `(try 
      (println "line 8: try")
      ~bindings
      (catch Throwable e# e#))

  (if (= (count bindings) 0)
     `(try ~code
           (catch Throwable e# e#))
     `(let ~(subvec bindings 0 2)
                              (try
                                (safe ~(subvec bindings 2) ~@code)
                                (catch Throwable e# e#)
                                (finally
                                 (. ~(bindings 0) close)))))))

<小时>

我正在努力完成一项作业,但没有任何辅导是不可能的.我的老师希望我们在 1 周内自学 Clojure 并完成这项作业.我班上的每个人都被困住了,我们已经讨厌老师了,lmao.


OLD

I'm trying to get an assignment done, but it's impossible without any tutoring. My teachers expect us to teach ourselves Clojure in 1 week and complete this assignment. Everyone in my class is stuck and we already hate the teacher, lmao.

好的,所以宏应该能够尝试代码,并返回结果或异常.它应该能够处理如下表达式:

Okay, so the macro is supposed to be able to try code, and return a result or an exception. It's supposed to be able to handle expressions like:

(def v (safe [s (FileReader. (File. "file.txt"))] (. s read)))

如果代码打开了任何文件流或诸如此类的东西,它应该在 finally 子句中关闭它们.这就是我到目前为止所得到的——我意识到它不起作用.

If the code opened any filestreams or whatnot, it should close them in a finally clause. This is what I got so far - I realize it's not working.

(defmacro safe [& body]
`(try ~@body 
 (catch Throwable e# e#)
 (finally 
   (if (. ~@body isInstance Closable) (. ~@body close)))))

我得到的错误是:

无法解析符号:s 在此上下文中,编译:(NO_SOURCE_PATH:1)

Unable to resolve symbol: s in this context, compiling:(NO_SOURCE_PATH:1)

我绝望了,所以我尝试了很多不同的东西,我尝试了:

I got desperate so I tried alot of different stuff, I tried:

to edit the macro:

(defmacro safe [& body]
`(try ~@body 
      (catch Throwable e# e#)
      (finally (if (. ~@body isInstance Closable) (. ~@body close)))))

然后运行:

(safe (. (java.io.FileReader. (java.io.File. "C:/Users/Dyallo.L/Dropbox/DVK11/PROP/Clojure/txt.txt")) read))

导致:

没有这样的变量:clooj.cemerick.pomegranate/Closable,编译:(NO_SOURCE_PATH:1)

No such var: clooj.cemerick.pomegranate/Closable, compiling:(NO_SOURCE_PATH:1)

有人提到了 WITH-OPEN 宏,但我想这不适用于我的通用宏.宏不是用来打开文件的,但如果是,它肯定应该关闭它们.

Someone mentioned the macro WITH-OPEN but I guess that won't work well with my generic macro. The macro isn't meant for opening files, but if they are, it should definately close them.

太糟糕了,你不会帮我一下 Stackoverflow-geniuses 吗?预先感谢.

So darn, won't you give me a hand Stackoverflow-geniuses? Thanks in beforehand.

推荐答案

with-open 做同样的事情.

with-open macro does exactly the same thing.

如果有变量(可以多个)绑定到创建的对象,它会将 body 包装到 try-catch 块与 finally关闭.

If there is variable (can be more than one) bound to created object it wraps the body to try-catch block with finallyclosing.

(macroexpand-1 '(with-open [f (FileReader. (File. "1.txt"))]
                  (do this with f)
                  (do that with f)))

=>
(clojure.core/let
 [f (FileReader. (File. "1.txt"))]
 (try (clojure.core/with-open []
        (do this with f)
        (do that with f))
      (finally (. f clojure.core/close))))

如果没有绑定,则只返回正文

If there are no bindings then it just returns the body

(macroexpand-1 '(with-open []
                  (do this with f)
                  (do that with f)))

=>
(do (do this with f)
    (do that with f))

更新. Arthur 已经解释了您问题的例外"部分.

Update. Arthur has already explained "exception" part of your question.

这篇关于Clojure:try,catch 宏,它也关闭任何文件流(不是打开)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆