实现重载算子协议方法的所需形式在“extend-**”宏和“defrecord”之间不一致。
“extend”宏系列要求重载的方法定义遵循与defn相同的形式
(method ([arg1] ...) ([arg1 arg2] ...))
然而,“defrecord”要求单独定义实现
(method [arg1] ...) (method [arg1 arg2] ...)
此外,如果你犯了错误,错误模式也不太有帮助。
如果你将“defrecord”形式与“extend-**”一起使用,它将成功评估,但后来的定义会静默覆盖先前的声明。
如果你将“extend-**”形式与“defrecord”一起使用,它将在方法的主体上产生关于“不受支持的绑定形式”的神秘错误。
这不是与CLJ-1056相同的问题:那涉及协议声明的语法,这个问题是与协议实现语法相关的问题。
`
(defprotocol MyProtocol
(mymethod
[this arg]
[this arg optional-arg]))
(extend-protocol MyProtocol
Object
(mymethod
([this arg] :one-arg)
([this arg optional-arg] :two-args)))
;; 错误!崩溃:"不支持的绑定形式::one-arg"
(defrecord MyRecord []
MyProtocol
(mymethod
([this arg] :one-arg)
([this arg optional-arg] :two-args)))
;; 支持...
(defrecord MyRecord []
MyProtocol
(mymethod [this arg] :one-arg)
(mymethod [this arg optional-arg] :two-args))
;; 评估...
(extend-protocol MyProtocol
Object
(mymethod [this arg] :one-arg)
(mymethod [this arg optional-arg] :two-args))
;; 但然后... 错误!"参数数量不正确"
(mymethod :obj :arg)
;; 有两个参数的版本可以被调用来...
(mymethod :obj :arg1 :arg2)
`