实现重载算子数协议方法的所需形式在“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)
`