4ZM*_*4ZM 2 idioms clojure preconditions
我有一个函数可以完成一些(可能很长)工作(defn workwork [x] ...)
,还有一些其他函数可以提前检查调用是否会成功(defn workwork-precondition-1 [x] ...)
。
workwork
每次调用时都应评估前置条件函数(例如使用:pre
)。前置条件函数也应该在单个函数中收集(和:ed)并直接供客户端代码使用(例如禁用按钮)。
在 Clojure 中解决此问题同时避免代码重复的惯用方法是什么?
特别是,有没有办法在不运行函数体的情况下评估函数的前提条件?
您可以将先决条件收集到一个函数中:
\n\n(defn foo-pre [x]\n (even? x))\n
Run Code Online (Sandbox Code Playgroud)\n\n然后在 -style 前提条件中调用该函数:pre
:
(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
(-> #'foo meta :arglists first meta)\n;= {:pre [(foo-pre x)]}\n
Run Code Online (Sandbox Code Playgroud)\n\n:arglists
对于任何其他类型的条目也是如此。
这里有两个注意事项:
\n\n:arglists
Var 元数据中自动生成的条目可能会被覆盖。覆盖:arglists
会导致上述类型的有用的自动生成的元数据被丢弃。
{:pre [(foo-pre x)]}
上述(-> #'foo meta \xe2\x80\xa6)
表达式返回的值包含作为foo-pre
文字符号\xe2\x80\x93 ,您有责任找出它在foo
定义点引用的函数。(这可能是可能的,也可能是不可能的,例如,foo
可以使用本地函数defn
在顶级let
或letfn
表单内进行。)foo-pre
最后,匿名函数可以使用:pre
and :post
,但目前没有机制可以从函数本身中提取它们。