感谢目前为止提供的所有帮助。这是我的新代码,有效。但并不完全像我希望的那样 我需要它来返回java异常(不要问我为什么)。 例如:
(safe (/ 1 0))
#<ArithmeticException java.lang.ArithmeticException: Divide by zero>
这就是我想要的。但是当我使用处理绑定等的其他代码子句时,我得到了Clojure异常:
(seefe [f(FileReader.(File. "C:/txtf.txt"))](. f read))
FileNotFoundException C:\txtf.txt (The system cannot find the file specified) java.io.FileInputStream.open (:-2)
我该怎么做才能防止这种情况,而是显示Java异常呢?
(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)))))))
我正在努力完成任务,但没有任何辅导就不可能。我的老师希望我们在一周内自学Clojure并完成这项任务。我班上的每个人都被困住了,我们已经讨厌老师了。
好的,所以宏应该能够尝试代码,并返回结果或异常。它应该能够处理如下表达式:
(def v (safe [s (FileReader. (File. "file.txt"))] (. s read)))
如果代码打开了任何文件流或诸如此类的东西,它应该在finally子句中关闭它们。 这是我到目前为止所得到的 - 我发现它不起作用。
(defmacro safe [& body]
`(try ~@body
(catch Throwable e# e#)
(finally
(if (. ~@body isInstance Closable) (. ~@body close)))))
我得到的错误是:
在此上下文中无法解析符号: 编译:(NO_SOURCE_PATH:1)
我绝望了所以我尝试了很多不同的东西,我试过了:
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))
导致:
没有这样的var:clooj.cemerick.pomegranate / Closable, 编译:(NO_SOURCE_PATH:1)
有人提到了WITH WITH OPEN的宏,但我想这对我的通用宏来说效果不好。该宏不适用于打开文件,但如果它们是,它应该肯定关闭它们。
所以,你不会给我一只手Stackoverflow-geniuses吗? 先谢谢你。
答案 0 :(得分:2)
with-open
macro完全相同。
如果有一个变量(可以多于一个)绑定到创建的对象,它会将body
封装到try-catch
块并关闭finally
。
(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))))
如果没有绑定,那么它只返回正文
(macroexpand-1 '(with-open []
(do this with f)
(do that with f)))
=>
(do (do this with f)
(do that with f))
更新。亚瑟已经解释了您的问题中的“例外”部分。
答案 1 :(得分:2)
从示例中看,传递给安全宏的第一个表单是名称表达式对[a (open-something "/foo/bar") b (oopen-something-else)]
的向量,后面是一些使用这些符号的表达式。如果我正确地解释了赋值,那么结果将非常类似于with-open和各种with-connection宏。在提交您的结果之前,值得仔细检查这个假设。如果宏被认为在其体内找到可关闭的值而至少对其结构有一些了解,那将会困难得多。