使用 :pre 和 :post 可以使信息更易读?

5
在Clojure中,我使用以下方式的 :pre:
user=> (defn cannot-take-empty [x] {:pre [((complement empty?) x)]} 1)
#'user/cannot-take-empty
user=> (cannot-take-empty #{})
AssertionError Assert failed: ((complement empty?) x)  user/cannot-take-empty (NO_SOURCE_FILE:186)

很好,但这并不能解释为什么在传递空集合时没有商业原因不合理(或者有超过五个元素的集合,或者有两个键存在但另一个不存在的集合,或者任何当天的规则)。如果前提条件使用私有函数,则对用户来说可能更加困惑。

在使用 :pre 和 :post 时,是否有一种提供更有用反馈(如错误消息)给用户的方法?


看一下这个答案:https://dev59.com/tWAf5IYBdhLWcg3wSQ4z#24874961。它有点丑,但应该能用。 - soulcheck
@soulcheck 我本来希望避免显式地抛出异常,这似乎有点像Java。 - George Simms
你总是可以将它包装在一个函数/宏中 (defn wrapper [c text] (if (not c) (throw (AssertionError. text)))),但是这样做并不好。 - soulcheck
1个回答

4

显然,前置条件和后置条件是为使用案例而设计的,在报告条款提供足够信息给开发人员的情况下。如果您希望提供更多的解释,最好使用assert

但是,您可以滥用整个条件总是被报告的事实,例如:

{:pre [(do "It can't be empty because of..."
           (seq x))]}

它会报告类似以下信息:

断言错误 断言失败:(执行“由于...,它不能为空”(seq x))...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接