当前位置:  开发笔记 > 编程语言 > 正文

我应该使用函数或宏来验证Clojure中的参数吗?

如何解决《我应该使用函数或宏来验证Clojure中的参数吗?》经验,为你挑选了1个好方法。

我在Clojure中有一组数字函数,我想验证参数.函数期望有许多类型的参数,例如正整数,百分比,数字序列,非零数字序列等.我可以通过以下方式验证任何单个函数的参数:

    将验证代码写入函数.

    编写通用函数,将参数和期望类型传递给它.

    编写通用宏,将参数和期望类型传递给它.

    其他我没有想到的.

Larry Hunter的一些Lisp代码是#3的一个很好的例子.(寻找test-variables宏.)

我的直觉是宏更合适,因为对评估的控制和编译时计算的潜力,而不是在运行时完成所有操作.但是,我没有遇到我正在编写的代码似乎需要它的用例.我想知道编写这样一个宏是否值得付出努力.

有什么建议?



1> Brian Carper..:

Clojure已经(没有文档记录,可能会有更改)支持fns的前后条件.

user> (defn divide [x y]
        {:pre [(not= y 0)]}
        (/ x y))
user> (divide 1 0)
Assert failed: (not= y 0)
   [Thrown class java.lang.Exception]

虽然有点难看.

我可能会编写一个宏,这样我就能以简洁的方式报告哪些测试失败了(引用并按字面打印测试).您链接到的CL代码看起来非常讨厌这个巨大的案例陈述.在我看来,Multimethods在这里会更好.你可以很容易地把这样的东西扔到一起.

(defmacro assert* [val test]
  `(let [result# ~test]              ;; SO`s syntax-highlighting is terrible
     (when (not result#)
       (throw (Exception.
               (str "Test failed: " (quote ~test)
                    " for " (quote ~val) " = " ~val))))))

(defmulti validate* (fn [val test] test))

(defmethod validate* :non-zero [x _]
  (assert* x (not= x 0)))

(defmethod validate* :even [x _]
  (assert* x (even? x)))

(defn validate [& tests]
  (doseq [test tests] (apply validate* test)))

(defn divide [x y]
  (validate [y :non-zero] [x :even])
  (/ x y))

然后:

user> (divide 1 0)
; Evaluation aborted.
; Test failed: (not= x 0) for x = 0
;   [Thrown class java.lang.Exception]

user> (divide 5 1)
; Evaluation aborted.
; Test failed: (even? x) for x = 5
;   [Thrown class java.lang.Exception]

user> (divide 6 2)
3


前提条件和后置条件记录在此处http://clojure.org/special_forms搜索条件图。
推荐阅读
mobiledu2402852413
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有