我正在尝试使用defrecord语法从另一个名称空间获取Clojure记录以实现协议,但是调用了“满足条件”吗?给出一个空指针异常。代码经过编译,我可以成功地在记录实例上调用协议的方法,只有我不能获得“满意”?去工作。我尝试使用“扩展”而不是在defrecord语法中实现协议,并且遇到了同样的问题。
记录(在导入协议的名称空间中):
(defrecord LoxFunction [declaration]
LoxCallable
(arity [this] (count (:params declaration)))
(call [this _ arguments]
(let [env (env/new-environment @globals)
env-with-params
(reduce
(fn [env [param argument]]
(env/define-pure env (:lexeme param) argument))
env
(map vector (:params declaration) arguments))]
(execute-block (:body declaration) env-with-params)))
Object
(toString [this]
(str "<fn " (-> declaration :name :lexeme) ">")))
以及另一个命名空间中的协议:
(defprotocol LoxCallable
(arity [this])
(call [this interpreter-variables arguments]))
在记录调用中调用“满足”时的错误是:
Execution error (NullPointerException) at interpr.interpreter/eval17428$fn (interpreter.clj:164).
core.clj: 144 clojure.core/instance?
core_deftype.clj: 536 clojure.core/find-protocol-impl
core_deftype.clj: 569 clojure.core/satisfies?
core_deftype.clj: 569 clojure.core/satisfies?
interpreter.clj: 164 interpr.interpreter/eval17428/fn
MultiFn.java: 229 clojure.lang.MultiFn/invoke
interpreter.clj: 176 interpr.interpreter/eval17432/fn
MultiFn.java: 229 clojure.lang.MultiFn/invoke
interpreter.clj: 203 interpr.interpreter/eval17457/fn
MultiFn.java: 229 clojure.lang.MultiFn/invoke
interpreter.clj: 266 interpr.interpreter/interpret
interpreter.clj: 261 interpr.interpreter/interpret
core.clj: 15 interpr.core/run
core.clj: 9 interpr.core/run
REPL: 91 interpr.core/eval17499
...等等。
编辑:代码调用是否令人满意?是:
(defmethod evaluate Call [expr]
(let [callee (evaluate (:callee expr))
arguments (map evaluate (:arguments expr))]
(cond
(not (satisfies? LoxCallable callee))
(throw (error/runtime-error "Can only call functions and classes." (:paren expr)))
(not (= (count arguments) (arity callee)))
(throw (error/runtime-error (:paren expr)
(str "Expected " (arity callee) " arguments but got " (count arguments) ".")))
:else
(call callee interpreter arguments))))
谢谢