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? %))
%)))