gpt4 book ai didi

java - Clojure:交叉引用变量、声明和编译错误

转载 作者:行者123 更新时间:2023-12-05 09:23:07 25 4
gpt4 key购买 nike

在一个命名空间中,我定义了两个变量(除其他外),它们是映射:

(declare bar)

(def foo {:is-related-to bar})

(def bar {:is-related-to foo})

因为当我定义 foobar 不存在,所以我使用 (declare bar) 向前声明它。

到目前为止没有任何问题,一切都在 REPL 中按预期工作。

我们唯一注意到的是,当我在 REPL 中检查 foo 时,我看到 bar 是未绑定(bind)的,我认为这是使用声明:

#<Unbound Unbound: #'user/bar>

当我尝试使用 lein jarlein ring war 编译软件时出现问题(因为它是一个 Ring 应用程序)。我从编译器得到的错误是:

Exception in thread "main" java.lang.RuntimeException: Can't embed object in code, maybe print-dup not defined: Unbound: #'user/bar, compiling...

我认为这也是意料之中的,因为我认为编译器无法处理未绑定(bind)的变量。

无论如何,如果所有这些行为都是意料之中的,那么为什么人们在无法编译的情况下使用前向声明呢?我可能在这里遗漏了一些东西。

最佳答案

您不能以这种方式构造循环引用。它不起作用的原因是因为 def 评估作为绑定(bind)传递的形式,并且评估解析为 Var 的符号获取该 Var 的当前绑定(bind)。换句话说,放入 map foo 的不是对 var bar引用,而是 。事后重新定义 bar 不会影响 foo 的值 - 这就是 Clojure 中的不可变性。

前向声明通常用于允许函数之间的循环依赖。以下是有效的,因为函数体在实际调用函数之前不会被评估;当函数被定义时,它确实是对被编译的 Var 的引用。

 (declare bar)

(defn foo [x y]
(bar x (* 2 y)))

(defn bar
([x] (foo x 3))
([x y] (+ x y)))

关于java - Clojure:交叉引用变量、声明和编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24167317/

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