gpt4 book ai didi

compilation - 由于语法错误,Clojure 后置条件无法执行——为什么?

转载 作者:行者123 更新时间:2023-12-01 11:55:14 25 4
gpt4 key购买 nike

在这个函数中:

(defn my-post 
[a]
{:post (number? %)}
a)

后置条件不会执行(或者至少不会导致断言错误)。我现在知道它应该是:

(defn my-post 
[a]
{:post [(number? %)]} ;; note the square brackets around the expression
a)

事实上,它确实可以正常工作。

问题是这无声地失败了,我花了一段时间才弄清楚出了什么问题。无语法错误、运行时异常。

我想了解 Clojure 对这段代码做了什么,以便理解为什么 Clojure 没有提示。 宏扩展?解构?如果看不到方括号,代码会不会消失?

最佳答案

http://clojure.org/special_forms记录 fn(因此也是 defn)的条件映射应该是以下形式:

{:pre [pre-expr*]
:post [post-expr*]}

{:post (number? %)} 将导致 (number? %) 被视为一系列断言,这意味着它被解释为两个单独的断言: number?%

user> (macroexpand-1 '(fn [a] {:post (number? %)} a))
(fn*
([a]
(clojure.core/let [% a]
(clojure.core/assert number?)
(clojure.core/assert %)
%)))

(assert number?) 始终通过,只要 number? 已定义并具有真值,这是一个核心函数,它可能会通过。如果 % 具有真值,则 (clojure.core/assert %) 通过。它通过 let 绑定(bind)到参数 a 的值,因此如果 a 具有真值,它就会通过。尝试使用您的第一个函数定义调用 (my-post nil),它会导致断言失败。

user> (my-post nil)
; Evaluation aborted.
; Assert failed: %
; [Thrown class java.lang.AssertionError]

如果你正确地将你的后置条件放在一个向量中,它会像这样扩展:

user> (macroexpand-1 '(fn [a] {:post [(number? %)]} a))
(fn*
([a]
(clojure.core/let [% a]
(clojure.core/assert (number? %))
%)))

关于compilation - 由于语法错误,Clojure 后置条件无法执行——为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7916740/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com