clojure.core/binding
的文档字符串说它“在隐式的 do 中执行表达式”。因此,我预计体内的元素将按顺序执行,并返回最后一个的表达式值(参看 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 年以来 hasn't changed,因此可能有一些合理的理由。如果有的话,那是什么?如果没有,我们能否将 binding
的实现改为实际上在 ~@body 周围有一个 do
呢?