【发布时间】:2014-09-30 17:55:23
【问题描述】:
Other 是What 的更复杂版本(包装)。它做了What 所做的事情,但更多。我小心地定义了 2 个命名空间。
(ns what)
(defprotocol IWhatever
(whatever [this]))
(deftype What []
IWhatever
(whatever [this]
(str "whatever")))
(whatever (->What))
(ns other (:require what))
(deftype Other []
what/IWhatever
(whatever [this]
(what/whatever (what/->What))))
(whatever (->Other)) ;bad line
错误是:
clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Unable to resolve symbol: whatever in this context, compiling:(C:\...)
为什么最后一个表达式不能解析?好像找不到名字,但是可以看到我在当前命名空间下重新定义了。
这是无意义的代码,但我使用了最简单的问题示例来说明这一点。如果相关,我会在 LightTable 中运行它。
【问题讨论】:
-
调用协议函数时,需要使用限定符号,即
(dict/get man :name),而不是(get man :name)。 -
它不会调用 Dictionary 版本,因为 Dictionary 中的版本没有实现。在 repl 中尝试一下,自己看看。
-
@Mario 我认为您错过了协议的重点。协议定义了一组多态函数。您调用一个协议函数,它根据第一个参数的类型进行调度。如果您必须为每种实现类型调用不同的函数,那将破坏整个目的。
-
当您在
Item上调用dict/get时,REPL 中会发生什么?你试过了吗? -
调用无法解析,因为
extend-type没有在当前命名空间中定义新函数。它将函数添加到正在扩展的协议的调度表中。
标签: clojure protocols clojurescript lighttable deftype