以下代码展示了两种定义带有约束的函数的方法。
=> 使用 with-constraints 宏按照预期工作
=> 使用 provide 宏在第二个约束时失败
(require '(link: clojure.core.contracts :as ccc))
;; 因为 provide 宏修改了 var-root,所以我们将保留两个单独的相同函数进行测试。
(defn qux (link: x) x)
(defn bar (link: x) x)
;; 定义两个约束
(def c1 (ccc/contract c1-cx "should be odd"))
(link: x)
(link: (odd? x))))
(def c2 (ccc/contract c2-cx "should have one digit"))
(link: x)
(link: (= 1 (count (str x))))))
;; 使用 provide 宏 => c1 被断言,c2 从未被断言。当我们交换 c2 和 c1 时,则 c2 被断言,c1 从未被断言
(ccc/provide (link: qux "qux" c1 c2))
;; 另一方面,使用 with-constraints 可以按预期工作。
(def qux-g)
(ccc/with-constraints bar c1 c2)
(qux 2);; 期望断言 "should be odd"
(qux 3);; 期望 3
(qux 23);; 期望断言 "only one digit",但得到 23
(qux-g 2);; 应该是奇数
(qux-g 3);; OK
(qux-g 23);; 应该是正数