代码之家  ›  专栏  ›  技术社区  ›  clartaq

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

  •  11
  • clartaq  · 技术社区  · 16 年前

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

    一些 Lisp code test-variables 宏。)

    有什么建议吗?

    3 回复  |  直到 16 年前
        1
  •  13
  •   Brian Carper    16 年前

    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]
    

    不过有点难看。

    (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
    
        2
  •  3
  •   Mark Bolusmjak    16 年前

    我觉得这取决于验证的复杂性和数量,以及函数的性质。

    如果您正在执行非常复杂的验证,那么应该将验证器从函数中分离出来。理由是你可以用简单的来构建更复杂的。

    例如,你写:

    1. 确认值大于零的验证器,
    2. 使用1和2确保值是大于零的非空值列表。

    如果您只是在做大量的简单验证,而问题是冗长(例如,您有50个函数都需要非零整数),那么宏可能更有意义。

        3
  •  1
  •   Arthur Ulfeldt    16 年前

    一个你 如果您希望修改语言以自动将测试添加到块中定义的任何函数中,例如:

    (with-function-validators [test1 test2 test4]  
        (defn fun1 [arg1 arg2] 
            (do-stuff))
        (defn fun2 [arg1 arg2] 
            (do-stuff))
        (defn fun3 [arg1 arg2] 
            (do-stuff)))  
    
    推荐文章