gpt4 book ai didi

validation - 我应该使用函数还是宏来验证 Clojure 中的参数?

转载 作者:行者123 更新时间:2023-12-03 08:14:20 25 4
gpt4 key购买 nike

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

  • 将验证代码直接写入
    功能。
  • 写一般
    目的函数,将其传递给
    参数和预期类型。
  • 编写通用宏,
    传递参数和
    预期类型。
  • 其他的我没想到。

  • 一些 Lisp code作者 Larry Hunter 是#3 的一个很好的例子。 (查找 test-variables 宏。)

    我的直觉是宏更合适,因为它可以控制评估,并且有可能在编译时进行计算,而不是在运行时全部完成。但是,对于我正在编写的似乎需要它的代码,我还没有遇到过用例。我想知道写这样一个宏是否值得。

    有什么建议吗?

    最佳答案

    Clojure 在 fn 上已经(未记录,可能会更改)支持前置和后置条件。 s。

    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 代码在那个巨大的 case 语句中看起来很糟糕。在我看来,多方法在这里会更好。你可以很容易地自己把这样的东西扔在一起。
    (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

    关于validation - 我应该使用函数还是宏来验证 Clojure 中的参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1640311/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com