在 core.clj 文件中定义的层次结构与在 REPL 中定义的层次结构



我正在执行"Practical Clojure"一书中的代码,关于层次结构,我有些不了解。也许有人可以给我一个关于我的问题的提示。提前感谢!

通过在一个莱宁根项目中添加以下代码:

 (derive ::human ::good)
 (derive ::elf ::good)

在一个 REPL 会话中,我正在执行(使用 :reload 'test.core),它返回 nil ~ 所以它被加载了。

(isa? ::human ::good) ; => false????

如果我在 REPL 中键入上述两种形式并使用相同的语法查询层次结构

(isa? ::human ::good) ; => true.

对于从 test.core.clj 文件加载的版本,我应该使用什么语法?我已经测试过,通过将另一种形式添加到core.clj是正确的

(def x (isa? ::human ::good) ; x is true. 

问候危险品

原因是以两个冒号开头的关键字被读取为命名空间关键字,其中命名空间是当前命名空间,除非您在短划线之前显式指定命名空间别名。

test.core ::human中读作:test.core/human 。在 REPL 中,您很可能在 user 命名空间中,因此它被读取为 :user/human - 一个不同的关键字!

您可以通过 (in-ns 'test.core) 切换到 test.core 命名空间。

或者,您可以完全限定关键字:

(isa? :test.core/human :test.core/good)

或者您可以使用别名来test.core

(require '[test.core :as test])
(isa? ::test/human ::test/good) ;; notice two colons: alias will be resolved

或者不能使用命名空间关键字。

(derive :human :elf)

这将是不惯用的,因为使用没有层次结构的derive作为第一个参数将更改全局层次结构(我们不想弄乱其他名称)。相反,您可以拥有自己的层次结构,您可以完全自己控制:

(def h (make-hierachy))
(derive h :human :elf)
(isa? h :human :elf)

如您所见,美丽的Clojure提供了许多适合或需求的方式。

最新更新