2

更新:

感谢到目前为止的所有帮助。这是我的新代码,它有效。但不完全是我想要的。
我需要它来返回 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)))))))

老的

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

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

(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)))))

我得到的错误是:

无法解析符号:s 在此上下文中,正在编译:(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))

结果是:

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

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

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

4

2 回答 2

2

从示例中可以看出,传递给安全宏的第一种形式是名称表达式对的向量,[a (open-something "/foo/bar") b (oopen-something-else)]然后是一些使用这些符号的表达式。如果我正确解释了分配,结果将与 with-open 和各种 with-connection 宏非常相似。当然,在提交您的结果之前,值得仔细检查这个假设。如果宏应该在其主体中找到可关闭的值而至少对其结构有一些了解,那将更加困难。

于 2013-01-10T17:06:19.510 回答
2

with-open做同样的事情。

如果有变量(可以是多个)绑定到创建的对象,它会用关闭包装bodytotry-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))

更新。亚瑟已经解释了你问题的“例外”部分。

于 2013-01-10T16:53:25.260 回答