如何在Clojure/Clojurescript中重用deftype方法?

ma2*_*a2s 6 clojure clojurescript

我正在尝试扩展库DomKM/silk.

具体来说,有deftype Route哪些实现协议Pattern,它有方法实现,我想在我的自定义Pattern协议实现中重用它.

https://github.com/DomKM/silk/blob/master/src/domkm/silk.cljx#L355

(deftype Route [name pattern]
  Pattern
  (-match [this -url]
          (when-let [params (match pattern (url -url))]
            (assoc params ::name name ::pattern pattern)))
  (-unmatch [this params]
            (->> (dissoc params ::name ::pattern)
                 (unmatch pattern)
                 url))
  (-match-validator [_]
                    map?)
  (-unmatch-validators [_]
                       {}))
Run Code Online (Sandbox Code Playgroud)

好的,所以我的实现看起来像这样,但我想"继承" Route的方法.我的意思是首先执行一些自定义逻辑,然后将其传递给原始Route方法.

(deftype MyRoute [name pattern]
  silk/Pattern
  (-match [this -url] 
    true) ;match logic here
  (-unmatch [this {nm ::name :as params}]
    true) ;unmatch logic here
  (-match-validator [_] map?)
  (-unmatch-validators [_] {}))
Run Code Online (Sandbox Code Playgroud)

怎么在clojure/clojurescript中完成?

小智 2

无需重新定义类型。从另一个命名空间引用“祖先”协议实现是可能的。

user=> (ns ns1)
nil
ns1=> (defprotocol P (f [o]))
P
ns1=> (deftype T [] P (f [_] 1))
ns1.T
ns1=> (f (T.))
1
ns1=> (ns ns2)
nil
ns2=> (defprotocol P (f [o]))
P
ns2=> (extend-protocol P ns1.T (f [o] (+ 1 (ns1/f o))))
nil
ns2=> (f (ns1.T.))
2
Run Code Online (Sandbox Code Playgroud)

请记住,ns1.Pns2.P是完全不同的猫,都称为P