clojure.core/binding
的文档字符串表示它 "在隐含的 do 中执行 exprs"。因此,我预期体中的元素将按顺序执行,并返回最后一个表达式的值(参见表达式 do 的文档字符串)。
然而,体表达式不是被包裹在 do
或 let
中,而是被包裹在 try
中。这允许出现一些令人惊讶的行为。
(binding [clojure.core/*print-length* 10]
(/ 10 0)
(catch Exception e
:failure))
上面的表达式返回 :failure
,而下面更明显地抛出编译器异常,因为无法在缺少 try
的情况下使用 catch
。
(binding [clojure.core/*print-length* 10]
(do
(/ 10 0)
(catch Exception e
:failure)))
根据我对 Git 历史的了解,自 2008 年以来这个实现细节没有改变,所以可能有些很好的理由。如果是这样,那是什么?如果不是,我们能否将 binding
的实现更改为在 ~@body
周围使用一个 do
?