实现重载参数数量协议方法的所需形式在 "extend-**" 宏和 "defrecord" 之间存在不一致性。
"extend" 宏系列要求重载方法定义遵循 defn 形式
(方法 ([arg1] ...) ([arg1 arg2] ...))
然而,"defrecord" 要求单独定义实现
(方法 [arg1] ...) (方法 [arg1 arg2] ...)
此外,如果您出错,错误模式并不友好。
如果您在 "extend-**" 中使用 "defrecord" 形式,它将成功评估,但后续定义会静默地覆盖词法上之前定义的内容。
如果您在 "defrecord" 中使用 "extend-**" 形式,它会在方法的主体上给出一个关于“不支持绑定形式”的神秘错误。
这不是与 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)))
;; 错误!崩溃并报错 "Unsupported binding form: :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)
`