有没有一种智能的方法来验证Clojure中的函数输入?

Lia*_*yan 8 validation clojure

我正在编写一个简单的DiceRoller应用程序并且我已经创建了主要函数,但是我想知道是否有一种"智能"方法来验证Clojure中的函数输入而不是使用分支条件来验证输入?我的功能在下面进行了一个样本测试,我还要测试n是不是一个数字与另一个if或an或它感觉很乱.

此外,如果任何人都可以指出一个更聪明的方式来做这个功能我会很感激任何反馈,这是我尝试编程功能的第一次尝试

(ns DiceRoller)

(defn roll
"rolls a specified number of n sided dice "
([] (roll 1 6))
([number] (roll number 6))
([number n]
  (if-not number? number (throw (IllegalArgumentException. (str "incorrect input, integers only"))))
  (take number (repeatedly #(+ (rand-int n) 1)))
  )
)
Run Code Online (Sandbox Code Playgroud)

Boz*_*sov 24

当然有 - 你可以使用:pre断言.

(defn some-fun [x]
  {:pre [(number? x)]}
  (foo x))
Run Code Online (Sandbox Code Playgroud)

现在你将得到AssertionError Assert失败:(数字?x)如果你传递一个非数字参数的函数x.

检查输入是否是一个数字是没有用的,因为@amalloy已经指出,但是有很多完全有效的前置条件(以及后置条件)检查你可能想要应用于你的函数.您可以在此处此处查看有关此主题的更多详细信息.


ama*_*loy 7

大多数情况下,Clojure的态度是"只是假设你做对了事".在这种情况下,如果您完全取出支票,用户最终会得到基本相同的异常.但如果你真的想这样做,你应该正确地做到这一点!现在你的代码会在每个输入上抛出一个异常,因为你错过了parens (number? number).

  • 当'反复'注意到`number`不是数字时,抛出自定义异常而不是"自动"异常更优雅? (2认同)
  • @amalloy,它使您有机会提供更有意义的错误消息。对于用户来说,这比期望他们解码重复抛出的任何异常要好得多。 (2认同)