以下代码展示了定义带约束函数的两种方式。
=> 使用 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 "应该是奇数"))
(link: x)
(link: (odd? x))))
(def c2 (ccc/contract c2-cx "应有一个数字"))
(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) ;; 预期断言 "应该是奇数"
(qux 3) ;; 结果是 3
(qux 23) ;; 预期断言 "只有一个数字",但我们得到 23
(qux-g 2) ;; 应该是奇数
(qux-g 3) ;; OK
(qux-g 23) ;; 应该是正数