在不运行函数的情况下检查 Clojure 前提条件?

4ZM*_*4ZM 2 idioms clojure preconditions

我有一个函数可以完成一些(可能很长)工作(defn workwork [x] ...),还有一些其他函数可以提前检查调用是否会成功(defn workwork-precondition-1 [x] ...)

workwork每次调用时都应评估前置条件函数(例如使用:pre)。前置条件函数也应该在单个函数中收集(和:ed)并直接供客户端代码使用(例如禁用按钮)。

在 Clojure 中解决此问题同时避免代码重复的惯用方法是什么?

特别是,有没有办法在不运行函数体的情况下评估函数的前提条件?

Mic*_*zyk 6

您可以将先决条件收集到一个函数中:

\n\n
(defn foo-pre [x]\n  (even? x))\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后在 -style 前提条件中调用该函数:pre

\n\n
(defn foo [x]\n  {:pre [(foo-pre x)]}\n  \xe2\x80\xa6)\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于使用 引入的函数,您可以从 Var 的元数据中defn提取-style 前提条件::pre

\n\n
(-> #'foo meta :arglists first meta)\n;= {:pre [(foo-pre x)]}\n
Run Code Online (Sandbox Code Playgroud)\n\n

:arglists对于任何其他类型的条目也是如此。

\n\n

这里有两个注意事项:

\n\n
    \n
  1. :arglistsVar 元数据中自动生成的条目可能会被覆盖。覆盖:arglists会导致上述类型的有用的自动生成的元数据被丢弃。

  2. \n
  3. {:pre [(foo-pre x)]}上述(-> #'foo meta \xe2\x80\xa6)表达式返回的值包含作为foo-pre文字符号\xe2\x80\x93 ,您有责任找出它在foo定义点引用的函数。(这可能是可能的,也可能是不可能的,例如,foo可以使用本地函数defn在顶级letletfn表单内进行。)foo-pre

  4. \n
\n\n

最后,匿名函数可以使用:preand :post,但目前没有机制可以从函数本身中提取它们。

\n