2

if在 Clojure 中,不匹配条件的表达式分支不会被计算,因此在计算以下表达式时不会引发异常:

=> (if nil (/ 1 0))
nil

但是,宏在评估 之前仍会被扩展if,因此您仍然可以获得如下异常:

=> (if nil (proxy [nil] []))
CompilerException java.lang.NullPointerException, compiling:(NO_SOURCE_PATH:1)

我正在编写一个宏,它的接口名称有时会作为 arg 提供,在这种情况下,宏将生成调用proxy. 其他时候,接口 arg 将是nil,然后宏扩展为类似的东西(if nil (proxy [nil] []),所以我得到了上面的异常。SSCE 将是:

=> (defmacro make-listener [listener-name & methods]
     `(if ~listener-name
        (proxy [~listener-name] []
          ~@(map (fn [m] `(~m [e#])) methods))))
#'user/make-listener
=> (make-listener java.awt.event.ActionListener actionPerformed)
#<Object$ActionListener$46793e3a user.proxy$java.lang.Object$ActionListener$46793e3a@ed5b2>
=> (make-listener nil)
CompilerException java.lang.NullPointerException, compiling:(NO_SOURCE_PATH:1) 

当没有提供接口 arg 时,如何以不引发异常的方式编写宏?

4

1 回答 1

4

如果 listener-name 为 nil,那么宏应该什么都不做,即您需要在宏扩展时检查 listener-name(不在宏发出的代码中)。

(defmacro make-listener [listener-name & methods]
  (if listener-name
     `(proxy [~listener-name] []
       ~@(map (fn [m] `(~m [e#])) methods)))) 
于 2013-04-02T08:56:51.323 回答