我正在尝试定义一个宏,该宏编写代码来为传入的表达式执行 try catch 块。
(defmacro safe
[expression]
`(try
~expression
(catch Exception e (str "caught exception: " (.getMessage e)))
)
)
Run Code Online (Sandbox Code Playgroud)
该宏写得很好,但是当我对其运行一些测试时,我收到以下编译器错误
seminar.core=> (def v (safe (/ 1 0)))
CompilerException java.lang.RuntimeException: Can't bind qualified name:seminar.core/e, compiling:(/private/var/folders/6f/q7lhngtn45q_xpzd_24gjp2h0000gn/T/form-init2350735096437822603.clj:1:8)
seminar.core=> (def v (safe (/ 10 2)))
CompilerException java.lang.RuntimeException: Can't bind qualified name:seminar.core/e, compiling:(/private/var/folders/6f/q7lhngtn45q_xpzd_24gjp2h0000gn/T/form-init2350735096437822603.clj:1:8)
Run Code Online (Sandbox Code Playgroud)
这就是宏的行为方式
user> (def v (safe (/ 1 0)))
user> v
#<ArithmeticException java.lang.ArithmeticException: Divide by zero>
user> (def v (safe (/ 10 2)))
user> v
5
Run Code Online (Sandbox Code Playgroud)
您需要e在宏中生成一个唯一的符号:
(defmacro safe
[expression]
`(try ~expression
(catch Exception e#
(str "caught exception: " (.getMessage e#)))))
Run Code Online (Sandbox Code Playgroud)
然后你就得到了想要的行为:
(safe (/ 1 0))
=> "caught exception: Divide by zero"
Run Code Online (Sandbox Code Playgroud)
请参阅此相关问题。后缀#是 的特殊简写gensym。这是必要的原因之一是,当宏展开时,宏中的绑定不会掩盖其他同名的绑定。
| 归档时间: |
|
| 查看次数: |
349 次 |
| 最近记录: |