实现arity-overloaded协议方法所需的形式在 "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)))
;; BAD! 由于 "Unsupported binding form: :one-arg" 而崩溃
(defrecord MyRecord []
MyProtocol
(mymethod
([this arg] :one-arg)
([this arg optional-arg] :two-args)))
;; Works...
(defrecord MyRecord []
MyProtocol
(mymethod [this arg] :one-arg)
(mymethod [this arg optional-arg] :two-args))
;; Evals...
(extend-protocol MyProtocol
Object
(mymethod [this arg] :one-arg)
(mymethod [this arg optional-arg] :two-args))
;; 但然后... 错误! "参数数量不正确"
(mymethod :obj :arg)
;; 2-arg版本可以调用...
(mymethod :obj :arg1 :arg2)
`