http://clojure.org/special_formsfn文件表明(因此也是)的条件图defn应采用以下形式:
{:pre [pre-expr*]
:post [post-expr*]}
{:post (number? %)}将导致(number? %)被视为一系列断言,这意味着它被解释为两个单独的断言:number?和%.
user> (macroexpand-1 '(fn [a] {:post (number? %)} a))
(fn*
([a]
(clojure.core/let [% a]
(clojure.core/assert number?)
(clojure.core/assert %)
%)))
(assert number?)只要number?定义并具有真实值,它就总是通过,这是一个核心功能,它可能确实如此。 (clojure.core/assert %)如果%有真值则通过。它通过 绑定到您的参数的值a,let因此如果a具有真值,它就会通过。尝试(my-post nil)使用您的第一个函数定义进行调用,它将使断言失败。
user> (my-post nil)
; Evaluation aborted.
; Assert failed: %
; [Thrown class java.lang.AssertionError]
如果你正确地将你的后置条件放在一个向量中,它会像这样展开:
user> (macroexpand-1 '(fn [a] {:post [(number? %)]} a))
(fn*
([a]
(clojure.core/let [% a]
(clojure.core/assert (number? %))
%)))