我正在执行"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提供了许多适合或需求的方式。